什麼是 Trie 樹?

2021-02-20 編程如畫

最近複習了 Trie 樹的相關知識,有了更加深刻的理解。想去打會遊戲放鬆下,突然接到了面試官的電話。

猿同學,看你簡歷上說熟悉數據結構,說說你對 Trie 樹的理解。

Trie 樹是一種多叉樹的結構,每個節點保存一個字符,一條路徑上的所有節點保存一個字符串。下圖表示了字符串:him 、 her 、 cat 、 no 、 nova 構成的 Trie 樹。從根節點到某一節點經過的字符連接起來構成一個字符串。如圖中的 him 、 her 、 cat 、 no 、 nova。在實現過程中,會在葉節點中設置一個標誌,用來表示該節點是否是一個字符串的結尾,本例中用青色填充進行標記。Trie 樹中每個節點存儲一個字符,從根節點到葉節點的一條路徑存儲一個字符串。另外,有公共前綴的字符串,他們的公共前綴會共用節點。如 her、 him 共用 h 節點。

Trie 樹的生成過程,就是不斷將字符串插入樹中。

以插入字符串 him 、 her 、 cat 、 no 、 nova 為例,過程如下:節點 i 不存在子節點 m,創建子節點 m。並將該節點標記為字符串結束標誌,完成 him 字符串插入。節點 e 不存在子節點 r,創建子節點 r。並將該節點標記為字符串結束標誌,完成 her 字符串插入。節點 a 不存在子節點 t,創建子節點 t。並將該節點標記為字符串結束標誌,完成 cat 字符串插入。節點 n 不存在子節點 o,創建子節點 o。並將該節點標記為字符串結束標誌,完成 no 字符串插入。節點 n 存在子節點 o,不用重新創建子節點 o。節點 v 不存在子節點 a,創建子節點 a。並將該節點標記為字符串結束標誌,完成 nova 字符串插入。情況一:待刪除的字符串末尾為葉節點,且與其它字符串無公共前綴。將節點逐一刪除即可,例如刪除 cat。情況二:待刪除字符串末尾不是葉節點。將字符串標誌位置為 false 即可,例如刪除 no 。情況三:待刪除字符串末尾為葉節點,並且中間有其它單詞。逐一刪除節點,直到待刪除節點是另一個字符串的結尾為止,例如刪除 nova。情況四:待刪除字符串某一節點還有其它子節點。逐一刪除節點,如果待刪除節點還有其它子節點,則停止刪除,例如刪除 him。

Trie 樹又叫字典樹。字典是用來查字的,Trie  樹最基本的作用是在樹上查找字符串。

例如有 5 個字符串:him 、 her 、 cat 、  no 、 nova 。現在要查找 catch 是否存在。如果使用暴力的方法,需要用 catch 與這 5 個字符串分別進行匹配,效率較低。如果將這 5 個字符串存儲成 Trie 的結構,只需要順著路徑依次比較,比較完 cat 之後,沒有節點與 c 匹配,所以字符串集合中不存在 catch。

寫一下 Trie 樹實現插入,檢索,刪除字符串的代碼。

struct trie_node{    int isKey = 0;     trie_node* child[26] = {nullptr}; };
void insert(string s, trie_node* root){ trie_node* p = root; for (auto c : s) { int n = c - 'a';        if (!p->child[n]) { trie_node* q =new trie_node; p->child[n] = q; } p = p->child[n]; }    p->isKey = 1;}
bool search(string s, trie_node* root){ trie_node* p = root; for (auto c : s) { int n = c - 'a'; if (!p->child[n]) return 0; p = p->child[n]; } if (p->isKey) return 1; return 0;}void remove(string s, trie_node* root){ if (!search(s, root)) return; stack<trie_node*> stkt; stack<int> stkc; trie_node* p = root; for (auto c : s) { int n = c - 'a'; stkc.push(n); stkt.push(p->child[n]); p = p->child[n]; } p->isKey = 0; while (!stkt.empty()) { trie_node* q; q = stkt.top(); if (q->isKey == 1) return; for (int i = 0; i < 26; i++) { if (q->child[i]) return; } delete q; stkt.pop(); stkt.top()->child[stkc.top()] = nullptr; stkc.pop(); }}

在構造樹的過程中,已經將所有字符串遍歷了一遍。可以在 Trie 樹節點的數據結構中,增加一個 count 來計數。對於每個字符串的插入操作,若已存在,計數加 1,若不存在,插入後 count 置為 1。要統計某個字符串出現的次數,只需要找到字符串結尾對應的節點,輸出對應節點的 count 值即可。
struct trie_node{    int isKey = 0;     int count = 0;    trie_node* child[26] = {nullptr}; };
void insert(string s, trie_node* root){ trie_node* p = root; for (auto c : s) { int n = c - 'a'; if (!p->child[n]) { trie_node* q =new trie_node; q->count += 1; p->child[n] = q; } p = p->child[n]; } p->isKey = 1;}
int count(string s, trie_node* root){ if(!search(s,root)) return 0; trie_node* p = root; for (auto c : s) { int n = c - 'a'; p = p->child[n]; } return p->count;}

Trie樹的核心思想是空間換時間,利用字符串的公共前綴來減少無謂的字符串比較以達到提高查詢效率的目的。

優點:插入和查詢的效率很高,都為O(m)。其中 m 是待插入/查詢的字符串的長度。

相關焦點

  • 深入理解Trie樹
    前言前面的文章介紹過各種高效的的數據結構,比如二叉搜索樹,AVL樹,紅黑樹,B樹,跳躍表等,今天我們再來學習一種多路樹,叫做Trie樹。
  • Trie 樹是什麼樣的數據結構?有哪些應用場景?
    與二叉查找樹不同,鍵不是直接保存在節點中,而是由節點在樹中的位置決定。一個節點的所有子孫都有相同的前綴,也就是這個節點對應的字符串,而根節點對應空字符串。讓我們一起來學習下它吧。一、什麼是Trie樹Trie樹,又叫字典樹、前綴樹(Prefix Tree)、單詞查找樹 或 鍵樹,是一種多叉樹結構。
  • 「算法與數據結構」Trie樹之美
    如果你還不了解什麼是Trie數據結構的話,或者知道一些,但是對於它具體是如何實現一個簡單Trie樹時,那麼這篇文章可能適合你閱讀。Trie樹中文名叫字典樹,前綴樹等,接下來我就以字典樹稱呼。我們來看下維基百科對它的描述吧⬇️在計算機科學中,trie,又稱前綴樹或字典樹,是一種有序樹,用於保存關聯數組,其中的鍵通常是字符串。
  • Trie樹結構
    之前說搜索提示的時候留了一個尾巴,就是Trie樹的結構沒有說,這一篇簡單的說一下Trie樹的實現方式。一個節點的所有子孫都有相同的前綴,也就是這個節點對應的字符串,而根節點對應空字符串。一般情況下,不是所有的節點都有對應的值,只有葉子節點和部分內部節點所對應的鍵才有相關的值。Trie這個術語來自於retrieval。根據詞源學,trie的發明者Edward Fredkin把它讀作英語發音:/ˈtriː/ "tree"。
  • 多叉樹,紅黑樹,堆,Trie樹,B樹,B+樹...
    應用場景:二叉查找樹的有序性是它能夠廣泛應用的原因。但是能否高效二分體現在樹的高度合理性上。下面要講的 紅黑樹/堆結構才是其廣泛應用。紅黑樹二叉查找樹的缺點在於:只限制了節點的有序性,但有序樹的構造有好壞。一顆「壞」的有序樹直接會被拉成 「有序鍊表」。所以需要通過一定的條件保證樹的平衡性。
  • 淺談樹形結構:多叉樹,紅黑樹,堆,Trie樹,B樹,B+樹...
    應用場景:二叉查找樹的有序性是它能夠廣泛應用的原因。但是能否高效二分體現在樹的高度合理性上。下面要講的 紅黑樹/堆結構才是其廣泛應用。紅黑樹二叉查找樹的缺點在於:只限制了節點的有序性,但有序樹的構造有好壞。一顆「壞」的有序樹直接會被拉成 「有序鍊表」。所以需要通過一定的條件保證樹的平衡性。
  • 三分鐘基礎:什麼是 trie 樹?
    來源:小小算法作者:小小算法「Trie [traɪ] 讀音和 try 相同,它的另一些名字有:字典樹,前綴樹,單詞查找樹等。開始之前我們先看看來 Trie 樹的幾個常見的應用場景:介紹 TrieTrie 是一顆非典型的多叉樹模型,多叉好理解,即每個結點的分支數量可能為多個。為什麼說非典型呢?
  • 字典樹 Trie Tree
    字典樹 Trie Tree 就是一個典型的記錄詞頻和前綴的數據結構。字典樹 Trie Tree字典樹,又稱前綴樹,通常用於詞頻統計、前綴統計、去重、排序等。如圖所示:圖中表示一棵 TrieTree,每個節點中的數字表示以該節點結尾的單詞的頻率,例如 go 單詞出現了4次。
  • 這是一顆Trie Tree!
    介紹 TrieTrie 是一顆非典型的多叉樹模型,多叉好理解,即每個結點的分支數量可能為多個。為什麼說非典型呢?因為它和一般的多叉樹不一樣,尤其在結點的數據結構設計上,比如一般的多叉樹的結點是這樣的:struct TreeNode { VALUETYPE value; //結點值 TreeNode* children[NUM]; //指向孩子結點};而 Trie 的結點是這樣的(假設只包含'a'~'z'中的字符):struct
  • 數據結構-Trie 字典樹
    字典樹主要用於存儲字符串,查找速度主要字符串元素(單詞)的長度有關O(w)。
  • 看動畫輕鬆理解「Trie樹」
    雖然發音與「Tree」一致,但為了將這種 字典樹 與 普通二叉樹 以示區別,程式設計師小吳一般讀「Trie」尾部會重讀一聲,可以理解為讀「TreeE」。Trie樹,也叫「字典樹」。顧名思義,它是一個樹形結構。它是一種專門處理字符串匹配的數據結構,用來解決在一組字符串集合中快速查找某個字符串的問題。
  • Prank betty什麼意思怎麼讀 Dox Artemis he's英語怎麼讀 Moy Lox...
    https://my.oschina.net/u/4313197/blog/3554323 大意: 將所有長度為2*n的合法括號序列建成一顆trie
  • 《玉樹後庭花》:「樹」是什麼樹?「花」是什麼花?
    好啦,我們回到主題:陳後主《玉樹後庭花》中的「玉樹」究竟是什麼樹?「後庭花」又是什麼花?一、「樹」是什麼樹?玉樹,很多人喜歡的肉肉植物,株高可達三米,葉片卵圓光潔,白色傘形花朵,碧葉素花相間,清雅而古樸,甚是好看。但是,這種植物原產於非洲,陳後主時期應該沒有這種舶來品。
  • B+樹是什麼意思 B+樹怎麼理解
    首頁 > 問答 > 關鍵詞 > b+樹最新資訊 > 正文 B+樹是什麼意思 B+樹怎麼理解
  • 漫畫:什麼是紅黑樹?
    二叉查找樹(BST)具備什麼特性呢?1.左子樹上所有結點的值均小於或等於它的根結點的值。2.什麼情況下會破壞紅黑樹的規則,什麼情況下不會破壞規則呢?我們舉兩個簡單的慄子:1.向原紅黑樹插入值為14的新節點:
  • 《哈嘍,樹先生》,到底是什麼打垮了樹先生
    《哈嘍,樹先生》這部劇看完後,老實說,我沒有得到啟迪,而且也沒有得到重現感,因為我發現我好像就是那個樹先生……電影的最後大家都已經知道,樹先生瘋了。然而到底是什麼打垮了樹先生呢?我給大家說下我的理解。我認為這句話適合樹先生。樹先生看上了城裡的聾啞女小梅,沒有什麼花前月下,也沒有鴻雁傳情,一個媒人,男大當婚女大當嫁,就這麼簡單,樹先生可以和小梅結婚。但是這是理論上,實際上呢?樹先生為了充面子,在村裡露個臉,讓自己的弟弟去借車接親,本來無可厚非,但是弟弟沒借來,還抱怨了兩句。作為兄長,長兄如父,弟弟如此的不尊重自己,還是在自己籌備婚禮期間,誰也受不了啊!