Trie,又称字典树,是一种用于实现字符串快速检索的多叉树结构。
Trie的每个节点都拥有若干个字符指针,若在插入或检索到一个字符串时扫描到一个字符c,就沿着当前节点的c这个字符指针,走向该指针指向的节点。
下面我们来详细讨论Trie的基本操作过程。
初始化
一棵空Trie仅包含一个根节点,该点的字符指针均指向空。
插入
当需要插入一个字符串S时,我们令一个指针P起初指向根节点。然后,一次扫描S中的每个字符c:1.当P的c字符指针指向一个已存在的节点Q,则令P=Q。
2.当P的c字符指针指向空,则新建一个节点Q,令P的c字符指针指向Q,然后令P=Q。
当S中的字符扫描完毕时,在当前节点P上标记它是一个字符串的末尾。
检索
当需要检索一个字符串S在Trie中是否存在时,我们令一个指针P起初指向根节点,然后一次扫描s中的每个字符c:1.若P的c字符指针指向空,则说明S没有被插入过Trie,结束检索。
2.若P的c字符指针指向一个已经存在的节点Q,则令P=Q。
当S中的字符扫描完毕时,若当前节点P被标记为一个字符串的末尾,则说明S在Trie中存在,否则说明S没有被插入过Trie.
可以看出在Trie中,字符数据都体现在树的边(指针)上,树的节点仅保存一些额外信息。例如单词结尾标记等。
其空间复杂度为O(NC),其中N是节点个数,C是字符集大小。
参考代码:
int trie[SIZE][26],tot=1; //初始化,假设字符串由小写字母构成
void insert (char* str) {//插入一个字符串
int len=strlen(str),p=1;
for(int k=0;k<len;k++){
int ch=str[k]-'a';
if(trie[p][ch]==0) trie[p][ch]=++tot;
p=trie[p][ch];
}
end[p]=true;
}
bool search(char* str) { //检索字符串是否存在
int len=strlen(str),p=1;
for(int k=0;k<len;k++){
p=trie[p][str[k]-'a'];
if(p==0) return false;
}
return end[p];
}