Trie樹的雙陣列實現

2021-06-16 19:18:27 字數 4788 閱讀 6451

正文組織

1.什麼是trie樹?

2.如何實現乙個trie樹?

3.三陣列trie(tripple-array trie)

4.雙陣列trie(double-array trie)

5.字尾壓縮

8.雙輸出池分配(double-array pool allocation)

9.實現dfa:determine finite automatic,

11.其他實現

12.參考文獻

什麼是trie樹?

如何實現乙個trie樹?

通常乙個dfa有一張狀態轉移表來表示,轉移表的行代表狀態機的各個狀態,列表示轉換字元。轉換表中第i行第j列的值表示在狀態i的情況下輸入字元j的時候的目標狀態。

這種表示方式能夠提供快速的遍歷,以為每乙個轉移都可以有乙個行號和列號進行索引。然而在空間上,這種表示形式則存在很大的浪費,因為對於trie樹,大多數的節點都只有少數的幾個分支,這邊使得轉移表中的大量的空間浪費了。

相對於轉移表表示方式,可以利用鍊錶的形式來儲存每個狀態的狀態轉移關係。但是由於鍊錶是乙個線性訪問結構,從而導致了trie樹的檢索效率下降。

為了保證trie樹的訪問效率和空間的不浪費,便有人提出了對轉移表進行壓縮的方法來實現trie樹。

1.[johnson1975]利用4個陣列來表示dfa,在trie樹的情況下可以精簡到3個陣列。這種方式下,狀態轉移表的行時以重疊的方式分配的,這樣使得那些空閒的單元能夠被其他的狀態利用。

2.[aoe1989]提出了對3個陣列的表示方式的一種改進,使得之用兩個陣列即可

三陣列trie樹

正如[aho+1985] page 144-146中所講到的,dfa壓縮表示可以通過四個陣列來表示,即default,base,next以及checkt四個陣列。然而由於僅用於資訊檢索的trie樹比此法分析要簡單許多,所以default陣列其實可以省略。因此乙個trie樹能夠利用三個陣列來實現。

結構

三陣列(tripple-array)結構有以下三個陣列組成:

1.base陣列:base陣列的每乙個元素都對應trie樹中的乙個節點。對於trie樹中的乙個節點s,node[s]表示該節點在陣列next和check陣列中的起始索引,該索引表示節點s在狀態轉移表中的行號。

2.next陣列:這個陣列與check陣列協同工作。它提供給乙個緩衝池以供trie樹的狀態轉移表的行所代表的的稀疏向量的空間分配。即,trie樹中的每乙個節點的狀態轉移向量都會儲存於next陣列中

3.check陣列:這個陣列與next陣列協同工作。它用於標記next陣列中的元素所屬的trie樹節點。這樣便允許相鄰的兩個空間分配給不同的節點。

定義1:假設狀態s下,輸入字元為c時的目標狀態為t,那麼會有check[base[s] + c] = s, next[base[s] + c] = t.該關係可以用下圖表示:

遍歷

t := base[s] + c;

if check[t] = s then

next state := next[t]

else

fail

endif

構造方式為了插入狀態s的乙個新的轉移,比如輸入字元為c則轉移到狀態t,那麼要求next[base[s] + c]這個位址單元必須可用。如果該位址單元是空的,那我們可以直接插入;否則的話要麼需要移動當前單元格所有的節點或者節點s的轉移向量需要重新調整位置。實際中根據調整二者的代價來決定重新調整哪個節點的轉移向量。在找到了空閒的位址單元來儲存轉移向量之後,轉移向量必須按照如下的方式進行重新計算。假設新的存放位址從b開始,則重新分配的過程如下所示:

雙陣列trie樹為了解決這個問題,[aoe1989]將陣列個數減少到了兩個。在雙陣列結構中,base陣列和next陣列合併為乙個陣列,從而該結構中只有兩個平行的陣列,即base和check陣列。

結構

在雙陣列trie樹中,陣列中的trie樹節點是直接在base陣列和check陣列之間進行連線的,而不像三陣列的表示中的那樣通過狀態號進行連線。

定義2:對於狀態s,如果輸入字元為c,則目標轉移狀態為t的這個轉移關係來說,base陣列和check陣列會有如下關係:check[base[s] + c] = s, base[s] + c = t.如下圖所示:

遍歷

t := base[s] + c;
if check[t] = s then
next state := t
else
fail
endif
構造雙陣列trie數的構建與三陣列trie樹的構建基本類似,不同點在於base陣列中空間分配:

字尾壓縮

[aoe1989]在此基礎上還提出了一種儲存壓縮的策略,這種策略通過將沒有分支的字尾儲存於乙個字串中,稱之為tail。這樣一來,那些沒有分支的節點訪問便簡化為字串的比較問題了。

(未完待續)

雙陣列trie樹

雙陣列trie double arraytrie 是trie樹的乙個簡單而有效的實現,由兩個整數陣列構成,乙個是base,另乙個是check。設陣列下標為i,如果base i check i 均為0,表示該位置為空。如果base i 為負值,表示該狀態為詞語。check i 表示該狀態的前一狀態,t...

雙陣列trie樹

原文 trie樹的陣列實現原理 trie retrieval tree 又稱字首樹,可以用來儲存多個字串,並且非常便於查詢。在trie中查詢乙個字串的時間只取決於組成該串的字元數,與樹的節點數無關。因此,它的查詢速度通常比二叉搜尋樹更快。trie的結構很簡單,每條邊表示乙個字元,從根節點到葉節點就可...

雙陣列TRIE樹原理

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!原貼 雙陣列trie樹原理 摘要 本文介紹了一種新的內部 內部排序的內部,也就是在記憶體裡 陣列結構的digital search演算法,叫做雙陣列,結合了陣列訪問的快速和鏈式儲存的壓縮。digital search樹的每一條弧在雙陣列中都可以以o...