在计算机科学中,trie,又称前缀树,是一种有序树,用于保存关联数组,其中的键一般是字符串。与二叉查找树不一样,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的全部子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。通常状况下,不是全部的节点都有对应的值,只有叶子节点和部份内部节点所对应的键才有相关的值。html
Trie 这个术语来自于 retrieval。根据词源学,trie 的发明者 Edward Fredkin 把它读做 /ˈtriː/ "tree"。可是,其余做者把它读做 /ˈtraɪ/ "try"。算法
在图示中,键标注在节点中,值标注在节点之下。每个完整的英文单词对应一个特定的整数。Trie 能够看做是一个肯定有限状态自动机,尽管边上的符号通常是隐含在分支的顺序中的。数组
键不须要被显式地保存在节点中。图示中标注出完整的单词,只是为了演示 trie 的原理。数据结构
trie 中的键一般是字符串,但也能够是其它的结构。trie 的算法能够很容易地修改成处理其它结构的有序序列,好比一串数字或者形状的排列。好比,bitwise trie 中的键是一串位元,能够用于表示整数或者内存地ide
Trie树是一种哈希树的变种,典型应用是用于统计,排序和保存大量的字符串(但不只限于字符串),因此常常被搜索引擎系统用于文本词频统计。它的优势是:利用字符串的公共前缀来节约存储空间,最大限度地减小无谓的字符串比较,查询效率比哈希表高。post
字典树与字典很类似,当你要查一个单词是否是在字典树中,首先看单词的第一个字母是否是在字典的第一层,若是不在,说明字典树里没有该单词,若是在就在该字母的孩子节点里找是否是有单词的第二个字母,没有说明没有该单词,有的话用一样的方法继续查找.字典树不只能够用来储存字母,也能够储存数字等其它数据。搜索引擎
相对来讲,Trie树是一种比较简单的数据结构.理解起来比较简单,正所谓简单的东西也得付出代价.故Trie树也有它的缺点,Trie树的内存消耗很是大.固然,或许用左儿子右兄弟的方法建树的话,可能会好点.url
其基本性质能够概括为:spa
1. 根节点不包含字符,除根节点外每个节点都只包含一个字符。code
2. 从根节点到某一节点,路径上通过的字符链接起来,为该节点对应的字符串。
3. 每一个节点的全部子节点包含的字符都不相同。
其基本操做有:查找 插入和删除,固然删除操做比较少见.我在这里只是实现了对整个树的删除操做,至于单个word的删除操做也很简单.
搜索字典项目的方法为:
(1) 从根结点开始一次搜索;
(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;
(3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。
(4) 迭代过程……
(5) 在某个结点处,关键词的全部字母已被取出,则读取附在该结点上的信息,即完成查找。
其余操做相似处理.
#define MAX 26 //字符集大小 enum NODE_TYPE{ DONE, UNDONE }; typedef struct TrieNode { enum NODE_TYPE type char ch; struct TrieNode *next[MAX]; //26-tree->a, b ,c, .....z }TrieNode; /*初始化*/ void InitTrieRoot(TrieNode **pRoot) { *pRoot = NULL; } /*建立新结点*/ TrieNode *CreateTrieNode(char ch) { int i; TrieNode *p = (TrieNode *)malloc(sizeof(TrieNode)); p->ch = ch; p->type= UNDONE; for(i =0 ; i < MAX ; i++) { p->next[i] = NULL; } return p; } /*插入*/ void InsertTrie(TrieNode **pRoot , char *s) { int i , k; TrieNode *p; if(!(p =*pRoot)) { p =*pRoot = CreateTrieNode(' '); } i =0; for(i=0;*(s+i)!='\0';i++) { k=s[i]-'a' if(!p->next[k]) p->next[k] = CreateTrieNode(s[i]); p = p->next[k]; } p->type=DONE; } //查找 int SearchTrie(TrieNode **pRoot , char*s) { TrieNode *p; int i , k; if(!(p =*pRoot)) { return 0; } i =0; while(s[i]) { k = s[i++] -'a'; if(p->next[k] == NULL) return 0; p = p->next[k]; } return (s[i] == '\0') && (p->type==DONE); }