数据结构与算法 - 字典树(Trie树)
字典树 (Trie),又称单词查找树、前缀树,是一种树形结构,是一种哈希树的变种。在统计、排序和保存大量的字符串(但不仅限于字符串)是具有更小的时间复杂度,因此可以应用于搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
例如我有 "a"、"apple"、"appeal"、"appear"、"bee"、"beef"、"cat" 这 7 个单词,那么就能够组织成如图所示字典树,如果我们要获取 "apple" 这个单词的信息,那么就按顺序访问对应的结点就行啦。
字典树的性质
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符;
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串;
- 每个节点的所有子节点包含的字符都不相同。
实现字典树
class Trie {
public:
Trie() {
this->children = vector<Trie *>(26, nullptr); // 每个节点可能有26个后继
this->isEnd = false; //若结点是单词的结尾,值为 true,否则为 false
}
bool insert(const string & word) {
Trie * node = this;
for (const auto & ch : word) {
int index = ch - 'a';
if (node->children[index] == nullptr) {
node->children[index] = new Trie();
}
node = node->children[index];
}
node->isEnd = true;
return true;
}
bool search(const string & word) {
Trie * node = this;
for (const auto & ch : word) {
int index = ch - 'a';
if (node->children[index] == nullptr) {
return false;
}
node = node->children[index];
}
return node != nullptr;
}
private:
vector<Trie *> children;
bool isEnd;
};