筆記整合 Trie樹

2021-09-23 20:33:35 字數 2291 閱讀 8757

trie樹,也叫「字典樹」。顧名思義,它是乙個樹形結構。它是一種專門處理字串匹配的資料結構,用來解決在一組字串集合中快速查詢某個字串的問題。

trie樹到底長什麼樣子?比如有6個字串,它們分別是:how,hi,her,hello,so,see。希望在裡面多次查詢某個字串是否存在。如果每次查詢,都是拿要查詢的字串跟這6個字串依次進行字串匹配,那效率就比較低,有沒有更高效的方法呢?

這個時候,就可以先對這6個字串做一下預處理,組織成trie樹的結構,之後每次查詢,都是在trie樹中進行匹配查詢。trie樹的本質,就是利用字串之間的公共字首,將重複的字首合併在一起。最後構造出來的就是下面這個圖中的樣子。

其中,根節點不包含任何資訊。每個節點表示乙個字串中的字元,從根節點到紅色節點的一條路徑表示乙個字串(注意:紅色節點並不都是葉子節點)。

trie樹主要有兩個操作,乙個是將字串集合構造成trie樹。這個過程分解開來的話,就是乙個將字串插入到trie樹的過程。另乙個是在trie樹中查詢乙個字串。

如何儲存乙個trie樹?經典的儲存方式

假設的字串中只有從a到z這26個小寫字母,在陣列中下標為0的位置,儲存指向子節點a的指標,下標為1的位置儲存指向子節點b的指標,以此類推,下標為25的位置,儲存的是指向的子節點z的指標。如果某個字元的子節點不存在,就在對應的下標的位置儲存null。

當在trie樹中查詢字串的時候,就可以通過字元的ascii碼減去「a」的ascii碼,迅速找到匹配的子節點的指標。比如,d的ascii碼減去a的ascii碼就是3,那子節點d的指標就儲存在陣列中下標為3的位置中。

public

class

trie

p = p.children[index];}

p.isendingchar =

true;}

// 在trie樹中查詢乙個字串

public

boolean

find

(char

pattern)

p = p.children[index];}

return p.isendingchar;

}public

class

trienode

}}

在trie樹中,查詢某個字串的時間複雜度是多少?如果要在一組字串中,頻繁地查詢某些字串,用trie樹會非常高效。構建trie樹的過程,需要掃瞄所有的字串,時間複雜度是o(n)(n表示所有字串的長度和)。但是一旦構建成功之後,後續的查詢操作會非常高效。

每次查詢時,如果要查詢的字串長度是k,那我們只需要比對大約k個節點,就能完成查詢操作。跟原本那組字串的長度和個數沒有任何關係。所以說,構建好trie樹後,在其中查詢字串的時間複雜度是o(k),k表示要查詢的字串的長度。

trie樹是一種非常獨特的、高效的字串匹配方法。但是,關於trie樹,你有沒有聽過這樣一種說法:「trie樹是非常耗記憶體的,用的是一種空間換時間的思路」。這是什麼原因呢?

trie樹用陣列來儲存乙個節點的子節點的指標。如果字串中包含從a到z這26個字元,那每個節點都要儲存乙個長度為26的陣列,並且每個陣列儲存乙個8位元組指標(或者是4位元組,這個大小跟cpu、作業系統、編譯器等有關)。而且,即便乙個節點只有很少的子節點,遠小於26個,比如3、4個,我們也要維護乙個長度為26的陣列。

trie樹的本質是避免重複儲存一組字串的相同字首子串,但是現在每個字元(對應乙個節點)的儲存遠遠大於1個位元組。按照上面舉的例子,陣列長度為26,每個元素是8位元組,那每個節點就會額外需要26*8=208個位元組。而且這還是只包含26個字元的情況。

如果字串中不僅包含小寫字母,還包含大寫字母、數字、甚至是中文,那需要的儲存空間就更多了。所以,也就是說,在某些情況下,trie樹不一定會節省儲存空間。在重複的字首並不多的情況下,trie樹不但不能節省記憶體,還有可能會浪費更多的記憶體。

trie樹儘管有可能很浪費記憶體,但是確實非常高效。那為了解決這個記憶體問題,是否有其他辦法呢?

可以稍微犧牲一點查詢的效率,將每個節點中的陣列換成其他資料結構,來儲存乙個節點的子節點指標。用哪種資料結構呢?選擇其實有很多,比如有序陣列、跳表、雜湊表、紅黑樹等。

綜合這幾點,針對在一組字串中查詢字串的問題,在工程中更傾向於用雜湊表或者紅黑樹。因為這兩種資料結構都不需要自己去實現,直接利用程式語言中提供的現成類庫就行了。

Trie 樹學習筆記

trie 樹是一種能夠高效的儲存和使用字串集合的一種東西。它的作用跟 texttt 十分相似,都是用來儲存字串集合的利器,但是,trie 樹卻比 texttt 的時間複雜度更加優秀。詳情見時空複雜度分析。trie 樹究竟是什麼東西呢?讓我們通過儲存乙個字串集合來直觀的了解它。已知我們要儲存這樣的字串...

學習筆記 字典樹(Trie)

日期 2020 08 25 目錄三 碎碎念 字典樹,英文名 trie。顧名思義,就是乙個像字典一樣的樹。可能有些不太形象,那我們舉個栗子叭 比如有乙個 duliu dalao daunting 令人望而生畏的 zhltao 那麼我們可以這麼存 仔細看看的話,其實挺像查字典的 我翻開一本如上的字典,翻...

演算法學習筆記 Trie 樹(字典樹)

2.3 trie 樹的適用範圍 3.總結 trie 樹,中文名為字典樹,是一種字串的高效處理演算法。trie 樹實現的功能就是快速的查詢一堆字串裡面有沒有某個串是另乙個串的字首,字尾等等。trie 樹首先是一棵樹,比如下面這棵樹就是一棵 trie 樹。這棵樹是由ab,abd,ac,bd四個字串構成的...