從bintree Trie 到三叉搜尋樹

2021-05-21 13:13:44 字數 935 閱讀 6649

最近在《程式設計師》雜誌上看到乙個.net大牛寫一篇《用三叉搜尋樹實現高效率的「自動完成」》的文章,感覺這種方法確實不錯。

對於字串的高效處理一般都是用字典樹——trie。雖然執行也是非常快,但是用這種資料結構需要消耗非常多的記憶體。trie是一種形似樹的資料結構,它的每個節點都包含乙個指標陣列,其中每乙個指標對應著字母表裡的乙個字母。從根節點開始,我們只要依次找到目標單詞裡下乙個字母對應的指標,就可以一步步追查到目標。

同樣,對於資料的處理一般也都是用bintree 和trie ,而遍歷表則可能不僅僅是26個字母,可能是按乙個或多個欄位的值為主鍵進行查詢的,表中可能有幾萬或百萬千萬個的元素。那麼就要充分考慮記憶體的消耗問題了。

pro*c對資料處理是先一次性資料上載到記憶體,然後對原始資料進行過濾、運算等處理,處理結束再後統一入庫。隨著上載記憶體的資料逐漸增多,資料操作越複雜,節點陣列中儲存的空指標占用的記憶體就越多。當記憶體耗用率達到一定界值後,程式的執行效率必然會急劇降低。這個可以參見《批量資料結構緩衝載入資料二叉樹查詢的效率優化測試》一文。

那麼可不可以用一種方法來解決這種問題呢?三叉搜尋樹就用了一種聰明的手段解決了trie 的記憶體問題。為了避免多餘的指標占用記憶體,每個trie節點不再用陣列來表示,而表示成「樹中有樹」。trie節點裡每個非空指標都會在三叉搜尋樹里得到屬於它自己的節點。

三叉搜尋樹包含三種型別的箭頭。第一種箭頭和trie裡的箭頭一樣的,沿著箭頭前進就意味著「匹配上」了箭頭起始端的元素。若沒有符合才會沿著向左或向右的箭頭前進。如果按照遍歷表的資料,我們要找的元素應該排在當前節點上元素的前面,我們就取左箭頭;反之則取右箭頭。

為了取得最佳效能,資料上載應該以隨機的順序插入到三叉樹中,不要排序插入。否則對應於單個trie節點的子樹會退化成煉表,極大地增加了查詢的成本。當然我們還可以用更複雜的方法來實現自平衡的三叉樹。

另外,切記不要超出實際需求而採用華麗的資料結構。如果遍歷表的資料量較小,那麼直接用bintree 就可以了。

三叉搜尋樹

三叉搜尋樹是用來解決字典樹的記憶體問題的資料結構。為了避免不需要的節點的記憶體占用,每個字典樹節點不再使用陣列,而是使用 樹中有樹 的結構。在三叉搜尋樹中,字典樹節點的每個非空指標得到它自己。例如,有四個單詞,ab abba abcd和bcd,它的三叉搜尋樹結構如下 三叉搜尋樹包括三種箭頭。第一種,...

三叉戟網路

今天為大家介紹一篇圖森科技在iccv 2019的目標檢測 scale aware trident networks for object detection 簡稱tridentnet,中文翻譯為三叉戟網路。位址見附錄。我們知道在目標檢測任務中,尺度變化一直是很關鍵的問題。針對尺度變化問題,也有很多的...

求三叉樹高度

有12345個結點的滿3叉數的高度為 寫出計算過程 1 層 1 節點數 1 2 3 4 層 2 節點數 3 5 6 7 8 9 10 11 12 13 層 3 節點數 9 滿三叉樹每層節點數目 假設k 1層有n個節點 那麼第k層就應該有3n個節點。也就是說這是乙個首項是1,公比是3的等比數列。第n層...