版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
前缀树的定义:
又称单词查找树,字典树,Trie树,是一种树形结构,是一种哈希树
的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高
。
前缀树的性质:
- 1)根节点不包含字符,除根节点外每一个节点都只包含一个字符
- 2)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
- 3)每个节点的所有子节点包含的字符都不相同
注:每个节点都含有26个链接表示出现的26个小写字母,即每个节点表示的字符是26个字符中的一个,当字符串插入完成时,我们就会标记该字符串就是完整的字符串了。
前缀树的操作:
前缀树的主要操作为插入,查找,删除(删除操作很少见)
源码如下:提供插入,查找及字符串的前缀字符操作
#include <iostream>
#include <string>
using namespace std;
class Trie {
private:
bool is_string;//当前节点是否为一个完整的字符串
Trie *next[26];//每个节点有26链接
public:
/** Initialize your data structure here. */
Trie() {
is_string=false;
memset(next,0,sizeof(next));//为next分配4个字节的内存空间
}
/** Inserts a word into the trie. */
void insert(string word) {
Trie* root=this;//根节点,根节点的节点值为空
for(const auto & w:word)//遍历字符串的每一个字符,若下一个节点不存在,则添加一个新节点
{
if(root->next[w-'a']==nullptr){root->next[w-'a']=new Trie();}
root=root->next[w-'a'];//根节点更新为新节点
}
root->is_string=true;//该字符串为完整的字符串
}
/** Returns if the word is in the trie. */
bool search(string word) {
Trie* root=this;//根节点
for(const auto & w:word)//遍历字符串,root每次更新为字符串中的节点值
{
if(root!=nullptr)root=root->next[w-'a'];
}
return (root!=nullptr&&root->is_string);
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Trie* root=this;//根节点
for(const auto & w:prefix)//遍历字符串,root每次更新为字符串中的节点值
{
if(root!=nullptr)root=root->next[w-'a'];
}
return (root!=nullptr);
}
};
int main()
{
Trie* trie = new Trie();
trie->insert("apple");
cout << trie->search("apple") << endl;
cout << trie->search("app") << endl;
cout << trie->startsWith("app") << endl;
trie->insert("app");
cout << trie->search("app") << endl;
system("pause");
}
前缀树的应用:
1、自动补全
2、拼写检查
3、IP路由(最长前缀匹配)
4、九宫格打字预测
5、单词打字游戏
前缀树与其他数据结构的优点: