Trie--字典樹

Trie--字典樹

在計算機科學中,trie,又稱前綴樹,是一種有序樹,用於保存關聯數組,其中的鍵一般是字符串。與二叉查找樹不一樣,鍵不是直接保存在節點中,而是由節點在樹中的位置決定。一個節點的全部子孫都有相同的前綴,也就是這個節點對應的字符串,而根節點對應空字符串。通常狀況下,不是全部的節點都有對應的值,只有葉子節點和部份內部節點所對應的鍵纔有相關的值。html

Trie 這個術語來自於 retrieval。根據詞源學,trie 的發明者 Edward Fredkin 把它讀做 /ˈtr/ "tree"。可是,其餘做者把它讀做 /ˈtr/ "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);   
}

 

Trie--字典樹

相關文章
相關標籤/搜索