字典樹 Trie Tree

2021-02-13 紅牛慕課

索引引擎通常需要統計詞頻,根據前綴給出搜索建議等。字典樹 Trie Tree 就是一個典型的記錄詞頻和前綴的數據結構。

字典樹 Trie Tree

字典樹,又稱前綴樹,通常用於詞頻統計、前綴統計、去重、排序等。

如圖所示:

圖中表示一棵 TrieTree,每個節點中的數字表示以該節點結尾的單詞的頻率,例如 go 單詞出現了4次。

而路徑表示組成單詞的每個字符,例如本圖例中表示:go、han、hank、java、jac、jack 幾個單詞的出現次數。

本結構即可統計詞頻。若需要統計前綴數量,在節點增加前綴計數器即可。

整體說,字典樹的特點如下:

路徑表示詞的組成

節點記錄需要統計的信息,例如詞頻和前綴量

根節點不記錄任何信息

任何節點的子節點路徑均不相同

以上結構在查詢單詞或前綴時效率很高,同時還可以記錄單詞的屬性,本例中就是頻率。

編碼Go

1// 字典樹
2type TrieTree struct {
3    Root *TrieNode
4}
5
6func NewTrieTree() *TrieTree {
7    return &TrieTree{
8        Root: NewTrieNode(),
9    }
10}
11
12// 字典樹節點
13type TrieNode struct {
14    Count       int                // 以當前節點為單詞結尾的數量
15    PrefixCount int                // 以當前節點為單詞前綴的數量
16    childNodes  map[rune]*TrieNode // 子節點
17}
18
19func NewTrieNode() *TrieNode {
20    return &TrieNode{
21        Count:       0,
22        PrefixCount: 0,
23        childNodes:  map[rune]*TrieNode{},
24    }
25}
26
27// 插入單詞
28func (tt *TrieTree) Insert(word string) {
29    if len(word) == 0 {
30        return
31    }
32    node := tt.Root
33    // 遍歷單詞的每個字符
34    for _, c := range strings.ToLower(word) {
35        // 若節點不存在,創建
36        if _, exists := node.childNodes[c]; !exists {
37            node.childNodes[c] = NewTrieNode()
38        }
39        // 繼續
40        node = node.childNodes[c]
41        // 累加前綴數量
42        node.PrefixCount++
43    }
44    // 累加結尾數量
45    node.Count++
46}
47
48// 查詢單詞次數
49func (tt *TrieTree) Search(word string) int {
50    if 0 == len(word) {
51        return 0
52    }
53    node := tt.Root
54    for _, c := range strings.ToLower(word) {
55        if _, exists := node.childNodes[c]; !exists {
56            return 0
57        }
58        node = node.childNodes[c]
59    }
60    return node.Count
61}
62// 查詢前綴次數
63func (tt *TrieTree) Prefix(word string) int {
64    if 0 == len(word) {
65        return 0
66    }
67    node := tt.Root
68    for _, c := range strings.ToLower(word) {
69        if _, exists := node.childNodes[c]; !exists {
70            return 0
71        }
72        node = node.childNodes[c]
73    }
74    return node.PrefixCount
75}
76
77// 測試
78func main() {
79    tt := NewTrieTree()
80    tt.Insert("Hank")
81    tt.Insert("hank")
82    tt.Insert("hanker")
83    tt.Insert("hanken")
84    fmt.Println(tt.Search("hank")) // 2
85    fmt.Println(tt.Prefix("hank")) // 4
86}

相關焦點

  • 什麼是 Trie 樹?
    節點 n 存在子節點 o,不用重新創建子節點 o。節點 v 不存在子節點 a,創建子節點 a。並將該節點標記為字符串結束標誌,完成 nova 字符串插入。情況一:待刪除的字符串末尾為葉節點,且與其它字符串無公共前綴。將節點逐一刪除即可,例如刪除 cat。情況二:待刪除字符串末尾不是葉節點。將字符串標誌位置為 false 即可,例如刪除 no 。情況三:待刪除字符串末尾為葉節點,並且中間有其它單詞。
  • 「算法與數據結構」Trie樹之美
    前言這次分享的Trie字典樹,是數據結構專題中的一個分支,認識了解Trie這種樹型數據結構,對構建算法與數據結構知識體系有一定的幫助。我對Trie樹的理解:把字符串都串接起來,消滅不必要的存儲,利用的就是字符串的公共前綴。
  • Trie 樹是什麼樣的數據結構?有哪些應用場景?
    ,又稱前綴樹或字典樹,是一種有序樹,用於保存關聯數組,其中的鍵通常是字符串。與二叉查找樹不同,鍵不是直接保存在節點中,而是由節點在樹中的位置決定。一個節點的所有子孫都有相同的前綴,也就是這個節點對應的字符串,而根節點對應空字符串。讓我們一起來學習下它吧。一、什麼是Trie樹Trie樹,又叫字典樹、前綴樹(Prefix Tree)、單詞查找樹 或 鍵樹,是一種多叉樹結構。
  • Trie樹結構
    之前說搜索提示的時候留了一個尾巴,就是Trie樹的結構沒有說,這一篇簡單的說一下Trie樹的實現方式。一個節點的所有子孫都有相同的前綴,也就是這個節點對應的字符串,而根節點對應空字符串。一般情況下,不是所有的節點都有對應的值,只有葉子節點和部分內部節點所對應的鍵才有相關的值。Trie這個術語來自於retrieval。根據詞源學,trie的發明者Edward Fredkin把它讀作英語發音:/ˈtriː/ "tree"。
  • 深入理解Trie樹
    前言前面的文章介紹過各種高效的的數據結構,比如二叉搜索樹,AVL樹,紅黑樹,B樹,跳躍表等,今天我們再來學習一種多路樹,叫做Trie樹。
  • 這是一顆Trie Tree!
    介紹 TrieTrie 是一顆非典型的多叉樹模型,多叉好理解,即每個結點的分支數量可能為多個。為什麼說非典型呢?因為它和一般的多叉樹不一樣,尤其在結點的數據結構設計上,比如一般的多叉樹的結點是這樣的:struct TreeNode { VALUETYPE value; //結點值 TreeNode* children[NUM]; //指向孩子結點};而 Trie 的結點是這樣的(假設只包含'a'~'z'中的字符):struct
  • 數據結構-Trie 字典樹
    字典樹主要用於存儲字符串,查找速度主要字符串元素(單詞)的長度有關O(w)。
  • 多叉樹,紅黑樹,堆,Trie樹,B樹,B+樹...
    應用場景:二叉查找樹的有序性是它能夠廣泛應用的原因。但是能否高效二分體現在樹的高度合理性上。下面要講的 紅黑樹/堆結構才是其廣泛應用。紅黑樹二叉查找樹的缺點在於:只限制了節點的有序性,但有序樹的構造有好壞。一顆「壞」的有序樹直接會被拉成 「有序鍊表」。所以需要通過一定的條件保證樹的平衡性。
  • 淺談樹形結構:多叉樹,紅黑樹,堆,Trie樹,B樹,B+樹...
    應用場景:二叉查找樹的有序性是它能夠廣泛應用的原因。但是能否高效二分體現在樹的高度合理性上。下面要講的 紅黑樹/堆結構才是其廣泛應用。紅黑樹二叉查找樹的缺點在於:只限制了節點的有序性,但有序樹的構造有好壞。一顆「壞」的有序樹直接會被拉成 「有序鍊表」。所以需要通過一定的條件保證樹的平衡性。
  • 雙語:男孩和樹(A Boy and His Tree)
    He climbed to the tree top, ate the apples, took a nap under the shadow… He loved the tree and the tree loved to play with him.   很久以前有一棵蘋果樹。一個小男孩每天都喜歡來到樹旁玩耍。他爬到樹頂,吃蘋果,在樹蔭裡打盹……他愛這棵樹,樹也愛和他一起玩。
  • A Special Tree 一棵特別的樹
    They were looking for a special tree.聖誕前幾周,爸爸和Celia去花園商場。他們要尋找一棵特別的樹。Dad pointed to a tall pine. Then Celia ran to a big round tree
  • 高中英語閱讀——The Tree and the Travelers(樹和旅行者)
    Being located near four towns, and many villages, the tree was an ideal meeting point for travelers.這棵樹位於四個城鎮和許多村莊附近,是旅行者的理想聚集地。
  • Merkle Tree(默克爾樹)算法解析
    於是往上推,依然是一樣的方式,可以得到數目更少的新一級哈希,最終必然形成一棵倒掛的樹,到了樹根的這個位置,這一代就剩下一個根哈希了,我們把它叫做 Merkle Root[3]。在p2p網絡下載網絡之前,先從可信的源獲得文件的Merkle Tree樹根。一旦獲得了樹根,就可以從其他從不可信的源獲取Merkle tree。通過可信的樹根來檢查接受到的Merkle Tree。
  • 什麼是前綴樹——打開了我的新思路
    前綴樹的概述前綴樹又名字典樹,單詞查找樹,Trie樹,是一種多路樹形結構,是哈希樹的變種,和hash效率有一拼,是一種用於快速檢索的多叉樹結構。典型應用是用於統計和排序大量的字符串(但不僅限於字符串),所以經常被搜尋引擎系統用於文本詞頻統計。它的優點是:最大限度地減少無謂的字符串比較,查詢效率比哈希表高。
  • 看動畫輕鬆理解「Trie樹」
    Trie樹Trie這個名字取自「retrieval」,檢索,因為Trie可以只用一個前綴便可以在一部字典中找到想要的單詞。  雖然發音與「Tree」一致,但為了將這種 字典樹 與 普通二叉樹 以示區別,程式設計師小吳一般讀「Trie」尾部會重讀一聲,可以理解為讀「TreeE」。Trie樹,也叫「字典樹」。顧名思義,它是一個樹形結構。它是一種專門處理字符串匹配的數據結構,用來解決在一組字符串集合中快速查找某個字符串的問題。
  • Regression Tree 回歸樹
    分類決策樹可用於處理離散型數據,回歸決策樹可用於處理連續型數據。由於我在學習GBDT算法時,了解到GBDT中的樹是回歸樹,但是在之前的學習中對於回歸樹了解比較少,這直接影響我對GBDT算法原理的理解。因此,本文首先簡單介紹回歸樹,然後詳細介紹CART回歸樹算法及流程,其次會給出完整的示例以加深理解,最後會討論ID3、C4.5能不能用來做回歸問題,及討論回歸樹的研究進展。2.
  • 「at the top of the tree」別理解成「在樹的頂端」
    大家好,歡迎來的餅哥英語的頻道,今天我們分享一個非常有用且地道的表達——at the top of the tree, 這個短語的含義不是指「在樹的頂端」,其正確的含義是:at the top of the tree (在職業或事業中)處於首要地位
  • 【默克爾樹】Merkle Tree理解起來並不難
    本期專題:默克爾樹本文原標題:Merkle Tree(默克爾樹)算法解析於是往上推,依然是一樣的方式,可以得到數目更少的新一級哈希,最終必然形成一棵倒掛的樹,到了樹根的這個位置,這一代就剩下一個根哈希了,我們把它叫做 Merkle Root。在p2p網絡下載網絡之前,先從可信的源獲得文件的Merkle Tree樹根。一旦獲得了樹根,就可以從其他從不可信的源獲取Merkle tree。
  • Python binarytree庫的用法介紹
    同時,binarytree 裡還實現了二叉搜索樹和堆,可以直接調用。一、安裝binarytree在binarytree庫中,可以供我們導入使用的有1個類和5個函數。下面會依次介紹每一個類或函數的用法。__all__ = ['Node', 'tree', 'bst', 'heap', 'build', 'get_parent']二、tree生成一棵普通二叉樹from binarytree import *tree0 = tree()print
  • 三分鐘基礎:什麼是 trie 樹?
    來源:小小算法作者:小小算法「Trie [traɪ] 讀音和 try 相同,它的另一些名字有:字典樹,前綴樹,單詞查找樹等。開始之前我們先看看來 Trie 樹的幾個常見的應用場景:介紹 TrieTrie 是一顆非典型的多叉樹模型,多叉好理解,即每個結點的分支數量可能為多個。為什麼說非典型呢?