在計算機科學中,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); }