字典树
字典树
概念
又称单词查找树,Trie
(读法类似try)树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
应用
- 串的快速检索
给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。
在这道题中,我们可以用数组枚举,用哈希,用字典树,先把熟词建一棵树,然后读入文章进行比较,这种方法效率是比较高的。 - “串”排序
给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序从小到大输出
用字典树进行排序,采用数组的方式创建字典树,这棵树的每个结点的所有儿子很显然地按照其字母大小排序。对这棵树进行先序遍历即可。 - 最长公共前缀
对所有串建立字典树,对于两个串的最长公共前缀的长度即他们所在的结点的公共祖先个数,于是,问题就转化为当时公共祖先问题。
以上内容摘自百度百科;
Java实现
import java.util.HashMap;
import java.util.Map;
public class Trie {
private Map<Character, Trie> next; // 更为通用的写法, 比用数组来表示孩子结点节约空间
private boolean isEnd;
public Trie() {
this.next = new HashMap<>();
this.isEnd = false;
}
public void insert(String word) {
Trie cur = this; // 获取根节点
for(char c : word.toCharArray()) {
if(cur.next.get(c) == null) // 如果该结点的孩子结点中无此字符, 则插入
cur.next.put(c, new Trie());
cur = cur.next.get(c); // 返回c对应的Trie对象
}
cur.isEnd = true; // 字符串结束位置字符的isEnd设为true, 表名字符串在这里结束
}
public boolean search(String word) {
Trie endNode = searchPrefix(word);
return endNode != null && endNode.isEnd;
}
public boolean startsWith(String prefix) {
Trie res = searchPrefix(prefix);
return res != null;
}
private Trie searchPrefix(String prefix) {
Trie cur = this;
for(char c : prefix.toCharArray()) { // 类似插入过程
if(cur.next.get(c) == null) return null;
cur = cur.next.get(c);
}
return cur;
}
}