Trie 樹構造原理 應用場景與複雜度分析

2021-09-07 20:40:55 字數 2210 閱讀 5090

字典樹,又稱 trie 樹,是一種專門用於字串匹配的樹形結構,能夠高效的在一組字串中尋找所求字串,與紅黑樹,雜湊表類似,但是又有其優勢。

如何構造一顆 trie 樹

假設我們有一組字串:abcadfadrfsiab

trie 樹的本質,就是利用字串之間的公共字首,將重複的字首合併在一起。如圖:

根節點不包含任何資訊,從根節點一路往下到灰色節點,便是乙個字串。

注意:灰色節點並不一定是葉子節點,當字串組中存在abcabcdfg這樣的時,前者是後者的字首,為了區分是兩個字串,需要給每個字串的結尾字元做標記。

在trie樹中查詢

假設我們要查詢abf,先將其拆分成 單個字元,按照下圖路徑,一層一層比較查詢。直到最後乙個字元恰好存在並且是灰色節點

如何構造一顆 trie 樹

上述分析可知,字典樹是一顆多叉樹,二叉樹中是通過左右子節點指標實現的,那麼多叉樹該如何實現呢?

//二叉樹

class

binarytreenode

假設當前字串只包含a-z26 個字元,那麼可以使用 26 個單位的子節點陣列來實現:

//字典樹單個節點類

public

class

triatree

}

public

class

trie

p = p.children[index];}

p.isendingchar =

true;}

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

public

boolean

find

(char

pattern)

p = p.children[index];}

return p.isendingchar;

}}

時間複雜度:

假設所有字串長度之和為n,構建字典樹的時間複雜度為o(n)

假設要查詢的字串長度為k,查詢的時間複雜度為o(k)

空間複雜度:

字典樹每個節點都需要用乙個陣列來儲存子節點的指標,即便實際只有兩三個子節點,但依然需要乙個完整大小的陣列。所以,字典樹比較耗記憶體,空間複雜度較高。

如何優化?

可以犧牲一點查詢的效率,將每個節點的子節點陣列用其他資料結構代替,例如有序陣列,紅黑樹,雜湊表等

例如,當子節點陣列採用有序陣列時,可以使用二分查詢來查詢下乙個字元。

縮點優化

將末尾一些只有乙個子節點的節點,可以進行合併,但是增加了編碼的難度。如圖

字典樹的缺陷:

需要處理的字串的字符集不能過大,否則儲存空間過於浪費,即便是採用優化方案,也是在犧牲部分查詢效能的基礎上的

在字串字首重合較多的情況,才有比較好的效能表現

沒有現成的字典樹可以用,如果要使用需要手寫,

字典樹中使用到了指標,因此前後節點是不連續的,對 cpu 快取不友好

而字典樹,則適合在查詢字首的場景下,例如,搜尋引擎一般在輸入部分字元後,會顯示一些預選關鍵字。這些關鍵字均是以輸入的字元為字首。

Mycat原理 應用場景

mycat的原理並不複雜,複雜的是 如果 也不複雜,那麼早就成為乙個傳說了。mycat的原理中最重要的乙個動詞是 攔截 它攔截了使用者傳送過來的sql語句,首先對sql語句做了一些特定的分析 如分 片分析 路由分析 讀寫分離分析 快取分析等,然後將此sql發往後端的真實資料庫,並將返回的結果做適當的...

Mycat原理 應用場景

mycat原理 mycat的原理並不複雜,複雜的是 如果 也不複雜,那麼早就成為乙個傳說了。mycat的原理中最重要的乙個動詞是 攔截 它攔截了使用者傳送過來的sql語句,首先對sql語句做了一些特定的分析 如分 片分析 路由分析 讀寫分離分析 快取分析等,然後將此sql發往後端的真實資料庫,並將返...

Mycat原理 應用場景

mycat原理 mycat的原理並不複雜,複雜的是 如果 也不複雜,那麼早就成為乙個傳說了。mycat的原理中最重要的乙個動詞是 攔截 它攔截了使用者傳送過來的sql語句,首先對sql語句做了一些特定的分析 如分 片分析 路由分析 讀寫分離分析 快取分析等,然後將此sql發往後端的真實資料庫,並將返...