实现 Trie 树

本文最后更新于:2022年4月9日 中午

参考:208. 实现 Trie (前缀树)@路漫漫我不畏

Trie 树,即字典树,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串,所以经常被搜索引擎系统用于文本词频统计。

核心思想:空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

优点:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

image-20210716220938055

基本性质:

  1. 根结点不包含字符,除根节点外每个节点都只包含一个字符。
  2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
  3. 每个节点的所有子节点包含的字符都不相同。

数据结构:

1
2
3
4
struct TrieNode {
bool isEnd; //该结点是否是一个串的结束
TrieNode* children[26]; //字母映射表
};

TrieNode结点中并没有直接保存字符值的数据成员,TrieNode* children[26]中保存了对当前结点而言下一个可能出现的所有字符的链接,因此可以通过一个父结点来预知它所有子结点的值:

1
2
3
4
5
6
7
8
for (int i = 0; i < 26; i++) {
char ch = 'a' + i;
if (parentNode->children[i] == NULL) {
说明父结点的后一个字母不可为 ch
} else {
说明父结点的后一个字母可以是 ch
}
}

Trie 的每个结点中都保留着一个字母表,这是很耗费空间的。如果 Trie 的高度为 n,字母表的大小为 m,最坏的情况是 Trie 中还不存在前缀相同的单词,那空间复杂度就为 O(m^n^)。

一次建树,多次查询

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class Trie {
public:
/** Initialize your data structure here. */
Trie() : isEnd(false), children(26, nullptr) {

}

/** Inserts a word into the trie. */
void insert(string word) {
Trie* node = this;
for (char c : word) {
if (node->children[c-'a'] == nullptr) {
node->children[c-'a'] = new Trie();
}
node = node->children[c-'a'];
}
node->isEnd = true;
}

/** Returns if the word is in the trie. */
bool search(string word) {
Trie* node = this;
for (char c : word) {
if (node->children[c-'a'] == nullptr)
return false;
node = node->children[c-'a'];
}
return node->isEnd;
}

/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Trie* node = this;
for (char c : prefix) {
if (node->children[c-'a'] == nullptr) {
return false;
}
node = node->children[c-'a'];
}
return true;
}
private:
bool isEnd;
vector<Trie*> children;
};

/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!