字典树、Trie树、前缀树
是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
Trie 是一颗非典型的多叉树模型,多叉好理解,即每个结点的分支数量可能为多个。
前缀树的特点:
-
查找或插入一个长度为 L 的单词,访问 next 数组的次数最多为 L+1,和 Trie 中包含多少个单词无关。
-
Trie 的每个结点中都保留着一个字母表,这是很耗费空间的。如果 Trie 的高度为 n,字母表的大小为 m,最坏的情况是 Trie 中还不存在前缀相同的单词,那空间复杂度就为
-
根节点不包含字符,除根节点外的所有子节点都只包含一个字符
-
每个节点的所有子节点包含的字符都不相同
-
每个节点保存了对当前结点而言下一个可能出现的所有字符的链接(我认为最重要的一点)
class Trie {
class TrieNode {
boolean isEnd = false;
TrieNode[] node = new TrieNode[26];
}
TrieNode trienode;
/** Initialize your data structure here. */
public Trie() {
trienode = new TrieNode();
}
/** Inserts a word into the trie. */
public void insert(String word) {
TrieNode cur = trienode;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.node[c - 'a'] == null) {
cur.node[c - 'a'] = new TrieNode();
}
cur = cur.node[c - 'a'];
}
cur.isEnd = true;
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
TrieNode cur = trienode;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.node[c - 'a'] == null) {
return false;
}
cur = cur.node[c - 'a'];
}
return cur.isEnd;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
TrieNode cur = trienode;
for (int i = 0; i < prefix.length(); i++) {
char c = prefix.charAt(i);
if (cur.node[c - 'a'] == null) {
return false;
}
cur = cur.node[c - 'a'];
}
return true;
}
}