字典树,是一种树型
的数据结构,又称 Trie树
、前缀树
,用于高效地存储、检索大量字符串。利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较。树中的边
来代表有无字符以及是哪个字符,每个节点
存储的信息有是否为单词结尾
以及后续字符是什么
。
字典树的性质:
1、根节点不表示字符串
2、从根节点到某个节点,经过路径上所有的字符连起来就是该节点对应的字符串
字典树节点里面存储的信息:
- 用一个
布尔值
表示从根节点到当前节点为止,该路径是否形成了一个有效(有意义)的字符串 - children 是个
数组
,里面存储指针
,每个指针代表一个不同的字符,指向子节点
字典树的操作:
insert
:向前缀树中插入
字符串search
:检索字符串。如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 falsestartWith
:如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false
C++实现:
该代码可在leetcode中剑指 Offer II 062. 实现前缀树通过
class Trie {
private:
struct TrieNode {
bool end;
std::vector<TrieNode*> children;
TrieNode() : end(false), children(26, nullptr) {}
~TrieNode() {
for (auto& c : children) {
delete c;
}
}
};
TrieNode *root;
public:
Trie() {
root = new TrieNode();
}
void insert(std::string word) {
TrieNode *p = root;
for (char w : word) {
int i = w - 'a';
if (p->children[i] == nullptr) {
p->children[i] = new TrieNode();
}
p = p->children[i];
}
p->end = true;
}
bool search(std::string word) {
TrieNode *p = root;
for (char w : word) {
int i = w - 'a';
if (p->children[i] != nullptr) {
p = p->children[i];
} else {
return false;
}
}
return p->end;
}
bool startsWith(std::string prefix) {
TrieNode *p = root;
for (char c : prefix) {
int i = c - 'a';
if (p->children[i] != nullptr) {
p = p->children[i];
} else {
return false;
}
}
return true;
}
};