Trie 樹是什麼樣的數據結構?有哪些應用場景?

2021-02-13 算法愛好者

(給算法愛好者加星標,修煉編程內功)

作者:神奕

blog.csdn.net/lisonglisonglisong/article/details/45584721

【前言】在計算機科學中,trie,又稱前綴樹字典樹,是一種有序樹,用於保存關聯數組,其中的鍵通常是字符串。
與二叉查找樹不同,鍵不是直接保存在節點中,而是由節點在樹中的位置決定。
一個節點的所有子孫都有相同的前綴,也就是這個節點對應的字符串,而根節點對應空字符串。

讓我們一起來學習下它吧。

一、什麼是Trie樹

Trie樹,又叫字典樹、前綴樹(Prefix Tree)、單詞查找樹 或 鍵樹,是一種多叉樹結構。

如下圖:


上圖是一棵Trie樹,表示了關鍵字集合{「a」, 「to」, 「tea」, 「ted」, 「ten」, 「i」, 「in」, 「inn」} 。從上圖可以歸納出Trie樹的基本性質:

通常在實現的時候,會在節點結構中設置一個標誌,用來標記該結點處是否構成一個單詞(關鍵字)。

可以看出,Trie樹的關鍵字一般都是字符串,而且Trie樹把每個關鍵字保存在一條路徑上,而不是一個結點中。

另外,兩個有公共前綴的關鍵字,在Trie樹中前綴部分的路徑相同,所以Trie樹又叫做前綴樹(Prefix Tree)。

二、Trie樹的優缺點

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

優點

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

關於查詢,會有人說 hash 表時間複雜度是O(1)O(1)不是更快?但是,哈希搜索的效率通常取決於 hash 函數的好壞,若一個壞的 hash 函數導致很多的衝突,效率並不一定比Trie樹高。

Trie樹中不同的關鍵字不會產生衝突。

Trie樹只有在允許一個關鍵字關聯多個值的情況下才有類似hash碰撞發生。

Trie樹不用求 hash 值,對短字符串有更快的速度。通常,求hash值也是需要遍歷字符串的。

Trie樹可以對關鍵字按字典序排序。‍‍‍‍

缺點當 hash 函數很好時,Trie樹的查找效率會低於哈希搜索空間消耗比較大。三、Trie樹的應用1、字符串檢索

檢索/查詢功能是Trie樹最原始的功能。思路就是從根節點開始一個一個字符進行比較:

struct trie_node{    bool isKey;       trie_node *children[26]; };

2、詞頻統計

Trie樹常被搜尋引擎系統用於文本詞頻統計 。

struct trie_node{    int count;       trie_node *children[26]; };

思路:為了實現詞頻統計,我們修改了節點結構,用一個整型變量count來計數。對每一個關鍵字執行插入操作,若已存在,計數加1,若不存在,插入後count置1。

注意:第一、第二種應用也都可以用 hash table 來做。

3、字符串排序

Trie樹可以對大量字符串按字典序進行排序,思路也很簡單:遍歷一次所有關鍵字,將它們全部插入trie樹,樹的每個結點的所有兒子很顯然地按照字母表排序,然後先序遍歷輸出Trie樹中所有關鍵字即可。

4、前綴匹配

例如:找出一個字符串集合中所有以ab開頭的字符串。我們只需要用所有字符串構造一個trie樹,然後輸出以a->b->開頭的路徑上的關鍵字即可。

trie樹前綴匹配常用於搜索提示。如當輸入一個網址,可以自動搜索出可能的選擇。當沒有完全匹配的搜索結果,可以返回前綴最相似的可能。

5、作為其他數據結構和算法的輔助結構

如後綴樹,AC自動機等。

四、Trie樹的實現

這裡為了方便,我們假設所有的關鍵字都由 a-z 的字母組成。

下面是 trie 樹的一種典型實現:

#include <iostream>#include <string>using namespace std;
#define ALPHABET_SIZE 26
typedef struct trie_node{ int count; trie_node *children[ALPHABET_SIZE]; }*trie;
trie_node* create_trie_node(){ trie_node* pNode = new trie_node(); pNode->count = 0; for(int i=0; i<ALPHABET_SIZE; ++i) pNode->children[i] = NULL; return pNode;}
void trie_insert(trie root, char* key){ trie_node* node = root; char* p = key; while(*p) { if(node->children[*p-'a'] == NULL) { node->children[*p-'a'] = create_trie_node(); } node = node->children[*p-'a']; ++p; } node->count += 1;}
int trie_search(trie root, char* key){ trie_node* node = root; char* p = key; while(*p && node!=NULL) { node = node->children[*p-'a']; ++p; }
if(node == NULL) return 0; else return node->count;}
int main(){ char keys[][8] = {"the", "a", "there", "answer", "any", "by", "bye", "their"}; trie root = create_trie_node();
for(int i = 0; i < 8; i++) trie_insert(root, keys[i]);
char s[][32] = {"Present in trie", "Not present in trie"}; printf("%s --- %s\n", "the", trie_search(root, "the")>0?s[0]:s[1]); printf("%s --- %s\n", "these", trie_search(root, "these")>0?s[0]:s[1]); printf("%s --- %s\n", "their", trie_search(root, "their")>0?s[0]:s[1]); printf("%s --- %s\n", "thaw", trie_search(root, "thaw")>0?s[0]:s[1]);
return 0;}

對於Trie樹,我們一般只實現插入和搜索操作。這段代碼可以用來檢索單詞和統計詞頻。

- EOF -

覺得本文有幫助?請分享給更多人

推薦關注「算法愛好者」,修煉編程內功

點讚和在看就是最大的支持❤️

相關焦點

  • 「算法與數據結構」Trie樹之美
    前言這次分享的Trie字典樹,是數據結構專題中的一個分支,認識了解Trie這種樹型數據結構,對構建算法與數據結構知識體系有一定的幫助。我對Trie樹的理解:把字符串都串接起來,消滅不必要的存儲,利用的就是字符串的公共前綴。
  • Trie樹結構
    在計算機科學中,trie,又稱前綴樹或字典樹,是一種有序樹,用於保存關聯數組,其中的鍵通常是字符串。與二叉查找樹不同,鍵不是直接保存在節點中,而是由節點在樹中的位置決定。一個節點的所有子孫都有相同的前綴,也就是這個節點對應的字符串,而根節點對應空字符串。一般情況下,不是所有的節點都有對應的值,只有葉子節點和部分內部節點所對應的鍵才有相關的值。Trie這個術語來自於retrieval。
  • 深入理解Trie樹
    前言前面的文章介紹過各種高效的的數據結構,比如二叉搜索樹,AVL樹,紅黑樹,B樹,跳躍表等,今天我們再來學習一種多路樹,叫做Trie樹。
  • 什麼是 Trie 樹?
    想去打會遊戲放鬆下,突然接到了面試官的電話。猿同學,看你簡歷上說熟悉數據結構,說說你對 Trie 樹的理解。Trie 樹是一種多叉樹的結構,每個節點保存一個字符,一條路徑上的所有節點保存一個字符串。下圖表示了字符串:him 、 her 、 cat 、 no 、 nova 構成的 Trie 樹。從根節點到某一節點經過的字符連接起來構成一個字符串。
  • 淺談樹形結構:多叉樹,紅黑樹,堆,Trie樹,B樹,B+樹...
    應用場景:二叉查找樹的有序性是它能夠廣泛應用的原因。但是能否高效二分體現在樹的高度合理性上。下面要講的 紅黑樹/堆結構才是其廣泛應用。紅黑樹二叉查找樹的缺點在於:只限制了節點的有序性,但有序樹的構造有好壞。一顆「壞」的有序樹直接會被拉成 「有序鍊表」。所以需要通過一定的條件保證樹的平衡性。
  • 多叉樹,紅黑樹,堆,Trie樹,B樹,B+樹...
    應用場景:二叉查找樹的有序性是它能夠廣泛應用的原因。但是能否高效二分體現在樹的高度合理性上。下面要講的 紅黑樹/堆結構才是其廣泛應用。紅黑樹二叉查找樹的缺點在於:只限制了節點的有序性,但有序樹的構造有好壞。一顆「壞」的有序樹直接會被拉成 「有序鍊表」。所以需要通過一定的條件保證樹的平衡性。
  • 盤點數據結構的應用場景
    數據結構是計算機編程中最重要的內容之一,我們經常會看到一個公式,那就是程序=數據結構+算法。從這個公式我們就能夠看出來數據結構是多麼的重要,要想寫出優雅高效的程序,一定離不開良好的數據結構,今天我們就來盤點一下常用的數據結構的應用場景。
  • 大數據實時分析平臺應用在哪些場景
    大數據平臺的應用場景,大致可分為如下幾個:
  • 數據結構-Trie 字典樹
    字典樹主要用於存儲字符串,查找速度主要字符串元素(單詞)的長度有關O(w)。
  • 人工智慧程式設計師入門應該學哪些算法?
    最短路徑算法最小生成樹算法二分圖的最大匹配 (匈牙利算法)最大流的增廣路算法(KM算法).三.數據結構.串排序(快排、歸併排(與逆序數有關)、堆排)簡單併查集的應用.哈希表和二分查找等高效查找法(數的Hash,串的Hash)哈夫曼樹堆trie樹(靜態建樹、動態建樹)四.簡單搜索深度優先搜索廣度優先搜索簡單搜索技巧和剪枝五.動態規劃背包問題.
  • 進銷存系統製作,根據應用場景設計數據表結構
    小夥伴們,上一節有給大家留一個任務,下拉菜單是如何實現的?如果大家有下載上一節的資料的話,可以用Custom UI Editor For Microsoft Office查看到相應的代碼。其實這個是splitButton(拆分按鈕)實現的,所有的菜單布局都需要通過組合這些控制項來實現,關鍵代碼如下所示。
  • 這是一顆Trie Tree!
    因為它和一般的多叉樹不一樣,尤其在結點的數據結構設計上,比如一般的多叉樹的結點是這樣的:struct TreeNode { VALUETYPE value; //結點值 TreeNode* children[NUM]; //指向孩子結點};而 Trie 的結點是這樣的(假設只包含'a'~'z'中的字符):struct
  • 數據結構快速盤點 - 非線性結構
    那麼有了線性結構,我們為什麼還需要非線性結構呢? 答案是為了高效地兼顧靜態操作和動態操作。大家可以對照各種數據結構的各種操作的複雜度來直觀感受一下。樹樹的應用同樣非常廣泛,小到文件系統,大到網際網路,組織架構等都可以表示為樹結構,而在我們前端眼中比較熟悉的 DOM 樹也是一種樹結構,而 HTML 作為一種 DSL 去描述這種樹結構的具體表現形式。如果你接觸過 AST,那麼 AST 也是一種樹,XML 也是樹結構。。。樹的應用遠比大多數人想像的要得多。
  • 快速入門數據結構和算法
    阿里妹導讀:有哪些常見的數據結構?基本操作是什麼?常見的排序算法是如何實現的?各有什麼優缺點?
  • 數據結構與算法-2
    舉例:從前有座山,山裡有座廟,廟裡有個老和尚講故事。講的是從前有座山,山裡有座廟(階乘、Fibonacci數列)。分治定義:map reduce的思想,把大的問題分解(Divide)成一個個小問題。把小問題的解(Conquer)一個個的合併(Combine)起來,分治是藉助遞歸去解決的。
  • 圖解:數據結構中的6種「樹」,你心中有數嗎?
    我們在學習數據結構時候,會遇到各種各樣的基礎數據結構,比如堆棧、隊列、數組、鍊表、樹...這些基本的數據結構類型有各自的特點,不同數據結構適用於解決不同場景下的問題。由於基礎二叉樹不利於數據的查找和插入,因此我們有必要對二叉樹中的數據進行排序,所以就有了「二叉查找樹」,可以說這種樹是為了查找而生的二叉樹,有時也稱它為「二叉排序樹」,都是同一種結構,只是換了個叫法。
  • 圖解:數據結構中的各種「樹」,你都心中有數嗎?
    我們在學習數據結構時候,會遇到各種各樣的基礎數據結構,比如堆棧、隊列、數組、鍊表、樹...這些基本的數據結構類型有各自的特點,不同數據結構適用於解決不同場景下的問題。今天就帶大家一起學習下,數據結構中的各種「樹」,這也是面試中經常考查的內容,手撕二叉樹是常規套路,對候選人也很有區分度,學完這篇文章,相信大家都會心中有「樹」了。從樹說起什麼是樹?現實中的樹大家都見過,在數據結構中也有樹,此樹非彼樹,不過數據結構的樹和現實中的樹在形態上確實有點相像。
  • 大數據入門:Hive應用場景
    在大數據的發展當中,大數據技術生態的組件,也在不斷地拓展開來,而其中的Hive組件,作為Hadoop的數據倉庫工具,可以實現對Hadoop集群當中的大規模數據進行相應的數據處理。今天我們的大數據入門分享,就主要來講講,Hive應用場景。
  • 三分鐘基礎:什麼是 trie 樹?
    來源:小小算法作者:小小算法「Trie [traɪ] 讀音和 try 相同,它的另一些名字有:字典樹,前綴樹,單詞查找樹等。開始之前我們先看看來 Trie 樹的幾個常見的應用場景:因為它和一般的多叉樹不一樣,尤其在結點的數據結構設計上,比如一般的多叉樹的結點是這樣的:struct TreeNode { VALUETYPE value; TreeNode* children[NUM]; };而 Trie 的結點是這樣的(假設只包含'a'~'z'中的字符):struct
  • 詳解數據分析六大經典模型原理及應用場景,值得收藏
    要想做好數據分析離不開數據分析模型的理解和掌握,掌握常用的數據分析模型能夠幫助我們拿到數據時很快理順分析的思路,提供一個分析的整體結構,另外也能更好幫助拆解問題,將問題細化,方便找出問題的主要原因。