题目
前缀树介绍:https://blog.youkuaiyun.com/DeveloperFire/article/details/128861092
什么是前缀树
在计算机科学中,trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。
trie 中的键通常是字符串,但也可以是其它的结构。trie 的算法可以很容易地修改为处理其它结构的有序序列,比如一串数字或者形状的排列。比如,bitwise trie 中的键是一串位元,可以用于表示整数或者内存地址。trie 树常用于搜索提示。如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能。
法1:迭代实现
class Trie {
private Trie[] children; //记录该字母的下一位所有可能的字母坐标
private boolean isEnd; //该字母是否为最后一个字母
public Trie() {
children = new Trie[26]; //初始化26个字母
isEnd = false; //默认为不是最后一个字母
}
public void insert(String word) {
Trie node = this; //得到字典树根节点
for (char c : word.toCharArray()) { //去遍历待插入单词的字符集合
int index = c - 'a'; //得到该字符在数组中的坐标
if (node.children[index] == null) { //如果正在遍历的该字母在上一个节点的数组坐标中没有记录,就新建一个字母节点在字典树中
node.children[index] = new Trie();
}
node = node.children[index]; //每一次生成字母都移动指针到下一个字母节点
}
node.isEnd = true; //最后一个字母节点设置为最后一个字母
}
public boolean search(String word) {
Trie node = searchPrefix(word); //返回检索到的最后一个字母节点
return node != null && node.isEnd; //只有当该单词在字典树中存在并且最后一个字母节点为最后一个字母,才返回true
}
public boolean startsWith(String prefix) {
return searchPrefix(prefix) != null; //只要前缀匹配存在于字典树中就返回true
}
/**
* 前缀搜索 还是 全文搜索都是调用此方法,区别在于前缀搜索只要前缀匹配就返回true,
* 全文搜索则要匹配到最后一个字母才返回true,所以这里返回的是最后一个字母节点
*/
public Trie searchPrefix(String word) {
Trie node = this; //得到字典树根节点
for (char c : word.toCharArray()) { //开始验证字符串在字典树中是否存在
int index = c - 'a'; //得到该字符在数组中的坐标
if (node.children[index] != null) { //如果该字符在数组中存在,就移动指针到下一个字母节点,直至到达最后一个待搜索的最后一个字母节点
node = node.children[index];
} else {
return null; //如果在此过程中没有找到待搜索的其中一个字母节点,就返回null,代表该字母不存在于字典树中
}
}
return node; //没有问题,那就是到达了最后一个待搜索的最后一个字母节点,返回该节点(节点可能是最后一个字母节点也可能不是)
}
}