字典樹Trie

來源:互聯網
上載者:User

標籤:

一、字典樹

字典樹——Trie樹,又稱為首碼樹(Prefix Tree)、單詞尋找樹或鍵樹,是一種多叉樹結構。

是一棵 Trie 樹,表示了關鍵字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 。從可以歸納出Trie樹的基本性質:

  • 根節點不包含字元,除根節點外的每一個子節點都包含一個字元。
  • 從根節點到某一個節點,路徑上經過的字元串連起來,為該節點對應的字串。
  • 每個節點的所有子節點包含的字元互不相同。

通常在實現的時候,會在結點結構中設定一個標誌,用來標記該節點處是否構成一個單詞(關鍵字)。

可以看出,Trie樹的關鍵字一般都是字串,而且Trie樹把每個關鍵字儲存在一條路徑上,而不是一個節點中。另外,有兩個公用首碼的關鍵字,在Trie樹種首碼部分的路徑相同。所以Trie又稱為首碼樹。

二、字典樹的優缺點優點
  1. 插入和查詢的效率很高,均是O(m),其中m是待插入/查詢的字串長度。

    • 關於查詢,有人會說hash表時間複雜度是O(1)不是更快?但是雜湊搜尋的效率取決於雜湊函數的好壞,若一個壞的hash函數導致了很多衝突,效率不一定比Trie樹高
  2. Trie樹中不同的關鍵字不會產生衝突。

  3. Trie樹中只有在允許一個關鍵字關聯多個值的情況下才有類似hash碰撞發生。

  4. Trie樹不用求hash值,對短字串有更快的速度。通常,求hash值也是需要遍曆字串的。

  5. Trie樹可以對關鍵字按照字典序排序。

    • 字典排序(lexicographical order)是一種對於隨機變數形成序列的排序方法。其方法是,按照字母順序,或者數字小大順序,由小到大的形成序列。
  6. 每一顆Trie樹都可以被看做一個簡單版的確定有限狀態的自動機(DFA,deterministic finite automation),也就是說,對於一個任意給定屬於該自動機的狀態(①)和一個屬於該自動機字母表的字元(②),都可以根據給定的轉移函數(③)轉到下一個狀態。其中:

    • ① 對於Trie樹的每一個節點都確定一個自動機的狀態。
    • ② 給定一個屬於該自動機字母表的字元,在圖中可以看到根據不同字元形成的分支;
    • ③ 從當前節點進入下一層次節點的過程進過狀態轉移函數得出。

    核心思想是:空間換時間,利用字串的公用首碼來減少無謂的字串比較以達到提高查詢效率的目的。

缺點
  1. 當hash函數很好時,Trie樹的尋找效率低於雜湊搜尋。

  2. 空間消耗大。

三、Trie樹的應用
  1. 字串檢索

    檢索、查詢功能是Trie樹最原始功能,思路就是從根節點開始一個一個字元進行比較。

    • 如果沿路比較,發現不同的字元,則表示該字串在集合中不存在。
    • 如果所有的字元全部比較並且完全相同,還需要判斷最後一個節點標識位(標記該節點是否為一個關鍵字)。
  2. 詞頻統計
    Trie樹常被搜尋引擎用於文本詞頻統計。
    思路:為了實現詞頻統計,我們修改了節點結構,用一個整型變數count來計數。對每一個關鍵字執行插入操作,若已存在,計數加1,若不存在,插入後count置 1。
    (1. 2. 都可以用hash table做)

  3. 字串排序
    Trie樹可以對大量字串按字典序進行排序,思路也很簡單:遍曆一次所有關鍵字,將它們全部插入trie樹,樹的每個結點的所有兒子很顯然地按照字母表排序,然後先序遍曆輸出Trie樹中所有關鍵字即可。

  4. 首碼匹配
    例如:找出一個字串集合中所有以ab開頭的字串。我們只需要用所有字串構造一個trie樹,然後輸出以a->b->開頭的路徑上的關鍵字即可。 trie樹首碼匹配常用於搜尋提示。如當輸入一個網址,可以自動搜尋出可能的選擇。當沒有完全符合的搜尋結果,可以返回首碼最相似的可能。

  5. 作為輔助結構
    如尾碼樹,AC自動機
    有窮自動機 參考資料:http://blog.csdn.net/yukuninfoaxiom/article/details/6057736

  6. 與雜湊表相比
    優點:

    • trie資料尋找與不完美雜湊表(鏈表實現)在最壞情況下更快;對於trie樹,最差為O(m),m為尋找字串的長度;對於不完美雜湊表,會有索引值衝突(不同鍵雜湊相同),最壞為O(N),N為全部字元產生的個數。典型情況是O(m)用於雜湊計算,O(1)用於資料尋找。

    • trie中不同鍵沒有衝突

    • trie的桶與雜湊表用於儲存鍵衝突的桶類似,僅在單個鍵與多個值關聯時需要

    • 當更多的鍵加入到trie中,無需提供hash方法或改變hash方法

    • trie通過鍵為條目提供字母順序
      缺點:

    • trie資料尋找在某些情況下(磁碟或隨機訪問時間遠遠高於主存)比雜湊表慢

    • 當索引值為某些類型(如浮點型),首碼鏈很長且首碼不是特別有意義。

    • 一些trie會比hash表更消耗記憶體。對於trie,每個字串的每個字元都要分配記憶體;對於大多數hash,只需要為整個條目分配一塊記憶體。

  7. 與二叉搜尋樹相比

    二叉搜尋樹,又稱二叉排序樹,它滿足:

    • 任意節點如果左子樹不為空白,左子樹所有節點的值都小於根節點的值;

    • 任意節點如果右子樹不為空白,右子樹所有節點的值都大於根節點的值;

    • 左右子樹也都是二叉搜尋樹;

    • 所有節點的值都不相同。

    其實二叉搜尋樹的優勢已經在與尋找、插入的時間複雜度上了,通常只有O(log n),很多集合都是通過它來實現的。在進行插入的時候,實質上是給樹添加新的葉子節點,避免了節點移動,搜尋、插入和刪除的複雜度等於樹的高度,屬於O(log n),最壞情況下整棵樹所有的節點都只有一個子節點,完全變成一個線性表,複雜度是O(n)。

    Trie樹在最壞情況下尋找要快過二叉搜尋樹,如果搜尋字串長度用m來表示的話,它只有O(m),通常情況(樹的節點個數要遠大於搜尋字串的長度)下要遠小於O(n)。

四、實現
#include <iostream>#include <string>using namespace std;#define ALPHABET_SIZE 26typedef struct trie_node{    int count;   // 記錄該節點代表的單詞的個數    trie_node *children[ALPHABET_SIZE]; // 各個子節點 }*trie;trie_node* create_trie_node(){    trie_node* pNode = new trie_node();    pNode->count = 0;    for(int i=0; i<ALPHABET_SIZE; ++i)        pNode->children[i] = NULL;    return pNode;}void trie_insert(trie root, char* key){    trie_node* node = root;    char* p = key;    while(*p)    {        if(node->children[*p-‘a‘] == NULL)        {            node->children[*p-‘a‘] = create_trie_node();        }        node = node->children[*p-‘a‘];        ++p;    }    node->count += 1;}/** * 查詢:不存在返回0,存在返回出現的次數 */int trie_search(trie root, char* key){    trie_node* node = root;    char* p = key;    while(*p && node!=NULL)    {        node = node->children[*p-‘a‘];        ++p;    }    if(node == NULL)        return 0;    else        return node->count;}int main(){    // 關鍵字集合    char keys[][8] = {"the", "a", "there", "answer", "any", "by", "bye", "their"};    trie root = create_trie_node();    // 建立trie樹    for(int i = 0; i < 8; i++)        trie_insert(root, keys[i]);    // 檢索字串    char s[][32] = {"Present in trie", "Not present in trie"};    printf("%s --- %s\n", "the", trie_search(root, "the")>0?s[0]:s[1]);    printf("%s --- %s\n", "these", trie_search(root, "these")>0?s[0]:s[1]);    printf("%s --- %s\n", "their", trie_search(root, "their")>0?s[0]:s[1]);    printf("%s --- %s\n", "thaw", trie_search(root, "thaw")>0?s[0]:s[1]);    return 0;}

對於Trie樹,我們一般只實現插入和搜尋操作。這段代碼可以用來檢索單詞和統計詞頻。

五、Trie樹改進
  1. 按位樹(Btiwise Trie):原理上和普通Trie樹差不多,只不過普通Trie樹儲存的最小單位是字元,但是Bitwise Trie存放的是位而已。位元據的存取由CPU指令一次直接實現,對於位元據,它理論上要比普通Trie樹快。

  2. 節點壓縮

    • ①分支壓縮: 對於穩定的Trie樹,基本上都是尋找和讀取的操作,完全可以把一些分支進行壓縮。例如,中最右側分支inn可以直接壓縮成一個節點“inn”,而不需要作為一個常規子樹存在。Radix樹就是根據這個原理來解決Trie樹過深的問題。

    • ②節點映射表:這種方式也是Trie樹節點可能幾乎完全確定下採用的,針對Trie樹節點的每一個狀態,如果狀態總數重複很多的話,通過一個元素為數位多維陣列(比如Triple Array Trie)來表示,這樣儲存Trie樹本身的空間開銷會小一些,雖然引入了額外的映射表。

  3. 雙數組TRIE樹(Double Array Trie)

    它在保證Trie樹檢索速度的前提下,提高空間利用率而提出的一種資料結構,本質上還是一個確定有限自動機。(所謂DFA就是一個能夠實現狀態專一的自動機,對於一個給定的屬於該自動機的狀態和一個資料該自動機字元表Σ的字元,它能夠根據預先給定的狀態轉移函數轉移到下一個狀態。)

    對於DAT來說,每個節點代表自動機的一個狀態, 根據變數的不同,進行狀態轉移,當達到結束狀態或者無法轉移時,完成查詢。

    參考資料:http://blog.csdn.net/zzran/article/details/8462002

六、Trie樹的其他形式

主要說明下這些演算法資料結構之間的關係。圖中黃色部分主要寫明了這些演算法和資料結構的一些關鍵點。

圖中可以看到這樣一些關係:extend-kmp 是kmp的擴充;ac自動機是kmp的多串形式;它是一個有限自動機;而trie圖實際上是一個確定性有限自動機;ac自動機,trie圖,尾碼樹實際上都是一種trie;尾碼數組和尾碼樹都是與字串的尾碼集合有關的資料結構;trie圖中的尾碼指標和尾碼樹中的尾碼連結這兩個概念及其一致。

七、Trie樹的效能比較

參考部落格 http://www.hankcs.com/nlp/performance-comparison-of-several-trie-tree.html

參考資料
  1. Trie樹 http://www.raychase.net/1783?replytocom=264917

  2. Trie樹 http://blog.csdn.net/v_july_v/article/details/6897097

  3. BitWise Trie http://blog.csdn.net/breeze_gao/article/details/8461856

  4. AC自動機 http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html

字典樹Trie

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.