Evanyou Blog 彩带

Trie字典树的学习及理解

字典树详解见

我这里学习时主要是看了李煜东的进阶指南里的讲解,以下是书中介绍的内容。

Trie,又称字典树,是一种用于实现字符串快速检索的多叉树结构,Tire的每个节点都拥有若干个字符指针,若在插入或检索字符串时扫描到一个字符c,就沿着当前节点的c这个字符指针,走向该指针指向的节点。

初始化时一颗空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是字符集的大小。

 

代码实现:

 

 1 // 假设字符串由小写字母构成
 2 int trie[SIZE][26], tot = 1;
 3 
 4 // Trie的插入
 5 void insert(char* str) {
 6     int len = strlen(str), p = 1;
 7     for (int k = 0; k < len; k++) {
 8         int ch = str[k]-'a';
 9         if (trie[p][ch] == 0) trie[p][ch] = ++tot;
10         p = trie[p][ch];
11     }
12     end[p] = true;
13 }
14 
15 // Trie的检索
16 bool search(char* str) {
17     int len = strlen(str), p = 1;
18     for (int k = 0; k < len; k++) {
19         p = trie[p][str[k]-'a'];
20         if (p == 0) return false;
21     }
22     return end[p];
23 }

 

posted @ 2018-03-07 12:14  five20  阅读(367)  评论(0编辑  收藏  举报
Live2D