Trie的删除和显示字典树全部内容

来源:10-7 更多和Trie字典树相关的话题

云霄9

2020-04-02

粗糙的实现了Trie的删除递归函数private boolean deleteWord(Node node, String word, int i).
返回为Boolean类型标量deleteSelf
思路:

递归终止条件:
  • 如果当待删除的字符不存在再当前Trie中,deleteSelf = false;
  • 如果当前字符已经是待删除节点的最后一个节点了,则若当前节点没有任何子节点了,设置当前节点为null且deleteSelf=true;否则设置node.isWord = false且deleteSelf=false;
持续递归(deleteWord(node.next.get©, word, i+1)
  • 若子节点不能被删除,则也不删除当前节点, deleteSelf=false;
  • 若子节点能被删除,考虑当前节点能不能被删除的情况:
    • 如果当前节点isWord=true;则表示它还是其他单词的词尾,不能删除.deleteSelf=false;
    • 如果当前节点isWord=false但是它的子节点不是空,则说明它是其他单词中间的一个字母,也不能删除.deleteSelf=false;
    • 如果上面两种情况都不满足,则可以删除:node=null and deleteSelf=true;
public void delete(String word) {
		if(root == null || word == null) {
			System.out.println("Null input or Empty Trie");
			return;
		}
		
		deleteWord(root, word, 0);
}
private boolean deleteWord(Node node, String word, int i) {
		boolean deleteSelf = false;
		
		if(node == null) {
			System.out.println("This word doesn't exist in Trie");
			return deleteSelf;
		}
		
		if(i == word.length()) {
			// 待删字符的最后
			if(node.next == null) {
			// 当前node底下没有任何节点了
				node = null;
				deleteSelf = true;
			}
			else {
			//当前node底下还有节点,直接将isWord改成false
				node.isWord = false;
				deleteSelf = false;
			}
		}
		else {
			char c = word.charAt(i);
			if(deleteWord(node.next.get(c), word, i+1)) {
				if(node.isWord) {
					// 当前节点是其他单词的结尾,不能删除
					deleteSelf = false;
				}
				else if(node.next != null) {
					// 当前节点底下还有其他节点,不能删除
					deleteSelf = false;
				}
				else {
					// 可以删除
					node = null;
					deleteSelf = true;
				}
			}
			else {
				deleteSelf = false;
			}
		}
		
		return deleteSelf;
}

为了方便直观的看结果,写了一个简单的display()…不知是否合理…;)
再本地测试时候基本能用

public void display() {
		char str[] = new char[26];
		display(root, str, 0);
	}
private void display(Node node, char[] str, int index) {
		
	if(node.isWord) {
		str[index] = '�';
		int i = 0;
		while(str[i] != '�') {
			System.out.print(str[i]);
			i++;
		}
		System.out.println();
	}
		
	for(char nextChar : node.next.keySet()) {
		if(node.next.get(nextChar) != null) {
			str[index]  = nextChar;
			display(node.next.get(nextChar), str, index+1);
		}
	}
}

我自己对于char str[] = new char[26]的部分有些介意…不知是否有更好的写法.总觉得这样就限制了输出的str单词长度再26个字母之内.

写回答

2回答

liuyubobobo

2020-04-03

感谢分享:)


如果不想用 char[26],只需要使用 ArrayList<Character>,就好了。每次递归前加入一个新字符;递归后产出最后一个字符,标准的回溯:)


当然,其实也可以直接使用 String,每次 display 传参传入 原来的 String + 新字符:)


继续加油!:)

0
1
云霄9
非常感谢!
2020-04-05
共1条回复

云霄9

提问者

2020-04-02

然后看到了老师的递归实现,感觉代码简洁多了,哈哈哈

0
0

玩转数据结构

动态数组/栈/队列/链表/BST/堆/线段树/Trie/并查集/AVL/红黑树…

6221 学习 · 1705 问题

查看课程