Double-Array Trie快速入門


shiqi.cui<cuberub@gmail.com>
May 24, 2009

1. Trie

  Trie是一種搜索樹,因“Retrieval”而得名。在以Trie樹組織的詞典里,所有詞條的公共前綴是壓縮存儲的,即只會存儲一份,所以又稱前綴樹。如圖所示:

  Trie樹結構示意圖

  Trie可以理解為確定有限狀態自動機,即DFA。在Trie樹中,每個節點表示一個狀態,每條邊表示一個字符,從根節點到葉子節點經過的邊即表示一個詞條。查找一個詞條最多耗費的時間只受詞條長度影響,因此Trie的查找性能是很高的,跟哈希算法的性能相當。

2. Trie存儲方式

  Trie可以按照樹的方式存儲。每個節點包含n個指針,分別指向n個后續節點,每條邊對應着一個輸入字符。這樣,每個節點的指針個數是跟字符表的大小相關的。如果按照鏈表的方式組織n個指針,查詢的效率會比較低;如果以定長數組表示n個指針,占用的空間會比較大,基本是不可接受的。

  Trie也可以按照DFA的方式存儲,即表示為轉移矩陣。行表示狀態,列表示輸入字符,(行, 列)位置表示轉移狀態。這種方式的查詢效率很高,但由於稀疏的現象嚴重,空間利用效率很低。也可以采用壓縮的存儲方式即鏈表來表示狀態轉移,但查詢效率無法滿足要求。

  為了解決上面的問題,有學者依次設計出了Four-Array Trie,Triple-Array Trie和Double-Array Trie結構,其得名源於內部采用的數組的個數。

3. Double-Array Trie

  Double-Array Trie包含base和check兩個數組。base數組的每個元素表示一個Trie節點,即一個狀態;check數組表示某個狀態的前驅狀態。

  base和check的關系滿足下述條件:

  base[s] + c = t

  check[t] = s

  其中,s是當前狀態的下標,t是轉移狀態的下標,c是輸入字符的數值。如圖所示:

4. 查詢過程

  根據上述公式,查找某個字符串就非常簡單。

  假設初始狀態為t0,字符序列是(c1, c2, …, cn)。那么,輸入c1后的狀態為t1 = base[t0] + c1,以此類推。

  如果到某個狀態是不合法的,那么查詢失敗;如果轉到狀態tn = base[tn-1] + c,並且tn是結束狀態,那么查詢成功;如果tn不是結束狀態,那么查詢失敗。

5. 構建過程

  首先,初始化base和check數組,元素默認值是0。隨機確定初始狀態t0及其base值,如t0=0, base[t0]=1。

  對於插入詞條,計算輸入每個字符后的base位置。

  如果該位置為空,則表示該位置可以插入,然后轉到下一個字符;

  如果該位置已有值,表示該位已經被其他的狀態占用,這樣需要調整其前驅狀態的base值,以保證狀態不會沖突,這個過程稱為relocate。

6. 參考文檔

  1. http://linux.thai.net/~thep/datrie/datrie.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM