1、字典树
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变形。典型应用是用于统计,排序和保存大量的字符串,所以经常被搜索引擎系统用于文本词频统计。它的优点是利用最大公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。
2、性质
-
根节点不包含字符,除根节点以外的每一个节点都只包含一个字符;
-
从根节点到某一节点,路径上经过的字符串连接起来,为该节点对应的字符串;
-
每个节点的所有子节点包含的字符都不相同。
3、实现方法
搜索字典项目的方法:
-
从根节点开始一次搜索;
-
取得要查找关键词的第一个字母,并根据该字母选择对应的子树继续进行检索;
-
在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索
-
迭代下去
-
在某个结点处,关键词的所在字母已被取出,则读取附在该结点上的信息,即完成查找。
4、应用
(1)串的快速检索
给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。
方法1:可以将英文文章中的所有单词逐个与熟词表进行比较,O(N)=O(n*avg(length1)*N*avg(length2)) = O(n*N)
方法2:采用hash表,
方法3:采用字典树,将该熟词表构成字典树,然后通过字典树进行查找。建树的时间复杂度:O(n) = O(N),查找的时间复杂度,只和树的深度相关,而与熟词表中有多少个单词无关,树的深度又与单词的长度有关,而单词最长不过30个字符,因此O(N)=O(1);另外在空间复杂度上又优于其他的算法,由于公共前缀的存在,不需要大量存储重复的字符。
(2)串的排序
给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序从小到大输出。
用字典树进行排序,采用数组的方式创建字典树,因为树的每个结点的所有子结点很显然是按照其字母大小排序的,那么对待这棵树进行先序遍历即可。
(3)最长公共前缀
对所有串建立字典树
字典树的代码:
#define MAX 10
typedef struct Trie
{
int v; //用于存储当前结点的公共前缀的字符串数目
Trie *next[MAX]; //用于存储当前结点的子节点数组
}Trie;
Trie *root = NULL;
void createTrie(char *str)
{
int length = strlen(str);
Trie *p = root, *q;
for(int i = 0;i<length;i++)
{
int id = str[i]-'0';
if(p->next[id] == NULL)
{
q = new Trie;
q->v = 1;
for(int j = 0;j<MAX;j++)
q->next[j] = NULL;
p->next[id] = q;
p = p->next[id];
}
else
{
p->v++;
p = p->next[id];
}
}
p->v = -1;
}
int FindTrie(char *str)
{
int length = strlen(str);
Trie *p = root;
for(int i = 0 ;i<length;i++)
{
int id = str[i] - '0';
p = p->next[id];
if(p == NULL)
return 0; //即该字符串不在此树上
if(p->v = -1)
return -1;//说明字典树中已经存在这样的字符串是str的前缀
}
return 1;//说明str是字典树中某字符串的前缀
}