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回答
-
感谢分享:)
如果不想用 char[26],只需要使用 ArrayList<Character>,就好了。每次递归前加入一个新字符;递归后产出最后一个字符,标准的回溯:)
当然,其实也可以直接使用 String,每次 display 传参传入 原来的 String + 新字符:)
继续加油!:)
012020-04-05 -
云霄9
提问者
2020-04-02
然后看到了老师的递归实现,感觉代码简洁多了,哈哈哈
00
相似问题