Trie 是一颗典型的多叉树模型,多叉好理解,即每个结点的分支数量可能为多个。
Trie 中一般都含有大量的空链接,因此在绘制一棵单词查找树时一般会忽略空链接,同时为了方便理解我们可以画成这样:
class Trie {
private:
bool isEnd;
Trie* next[26];
public:
Trie()
{
isEnd = false;
memset(next, 0, sizeof(next));
}
void insert(string word) {
Trie* node = this;
for (char c : word)
{
if (node->next[c - 'a'] == NULL)
{
node->next[c - 'a'] = new Trie();
}
node = node->next[c - 'a'];
}
node->isEnd = true;
}
bool search(string word)
{
Trie* node = this;//从根结点开始找
for (char c : word)
{
node = node->next[c - 'a'];
if (node == NULL)
{
return false;
}
}
return node->isEnd;
}
bool startsWith(string prefix) //和search的实现很类似,只是最后一句改一下即可
{
Trie* node = this;
for (char c : prefix)
{
node = node->next[c - 'a'];
if (node == NULL)
{
return false;
}
}
return true;
}
};
int main()
{
Trie*trie = new Trie();
trie->insert("apple");
cout << trie->search("apple") << endl; // 返回 true
cout << trie->search("app") << endl; // 返回 false
cout << trie->startsWith("app") << endl; // 返回 true
trie->insert("app");
cout << trie->search("app") << endl; // 返回 true
cout << trie->search("apple") << endl; // 返回 true
system("pause");
return 0;
}
字典树的应用详见820.单词的压缩编码(字典树)
最后补上前缀树的销毁:
写成静态成员函数也可以。
void Trie::deleteTrie(Trie*root)//递归销毁
{
for (int i = 0; i < 26; i++)
{
if (root->next[i] != NULL)
{
deleteTrie(root->next[i]);
}
}
delete root;
}