資料結構與演算法系列 字典樹

2021-07-10 09:35:33 字數 1883 閱讀 9649

一:背景

什麼是字典樹?

trie樹,即字典樹,又稱單詞查詢樹或鍵樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計和排序大量的字串(但不僅限於字串),所以經常被搜尋引擎系統用於文字詞頻統計。它的優點是:最大限度地減少無謂的字串比較,查詢效率比雜湊表高。trie的核心思想是空間換時間。利用字串的公共字首來降低查詢時間的開銷以達到提高效率的目的。

假如給出一些單詞,and,as,at,cn,com,構建下面的字典樹:

從上圖可以發現:

它有3個基本性質:

1.根節點不包含字元,除根節點外每乙個節點都只包含乙個字元。

2.從根節點到某一節點,路徑上經過的字元連線起來,為該節點對應的字串。

3.每個節點的所有子節點包含的字元都不相同。

你可能會想,這有什麼用?

第一:詞頻統計

可能有人要說了,詞頻統計簡單啊,乙個hash或者乙個堆就可以打完收工,但問題來了,如果記憶體有限呢?還能這麼玩嗎?所以這裡我們就可以用trie樹來壓縮下空間,因為公共字首都是用乙個節點儲存的。

第二: 字首匹配

就拿上面的圖來說吧,如果我想獲取所有以"a"開頭的字串,從圖中可以很明顯的看到是:and,as,at,如果不用trie樹,你該怎麼做呢?很顯然樸素的做法時間複雜度為o(n2) ,那麼用trie樹就不一樣了,它可以做到h,h為你檢索單詞的長度,可以說這是秒殺的效果。

二:完整**

#define _crt_secure_no_deprecate   

#define _crt_secure_cpp_overload_standard_names 1

#include#define max 26//假設字元只出現 abc..k..xyz 26個小寫英文本母

using namespace std;

struct node

};class trie

void add(node *node, const char *ch);

int find(const char *ch);

void delete(node *node, const char *ch);

};void trie::add(node *node, const char *ch)

add(node->next[order], ch + 1);//遞迴下去

}int trie::find(const char *ch)

} return p->num;

}void trie::delete(node *node, const char *ch)

delete(node->next[order], ch + 1);

}int main()

三:總結細心的朋友會發現,上面的**有缺陷,拿delete操作來說吧,if (len == 0 && node->next[order]->num != 0),這句**其實是有問題的,因為我沒有考慮node->next[order]->num==1的情況,如果等於1,現在執行刪除,自減1,num就是0了,也就是這個單詞從來沒出現,那麼表示這個 單詞這一條路徑都要delete(如果這條路徑上不存在其他的單詞),並且root處的指標需要reset。

好了,雖然**是有缺陷的,但是只要把實現搞懂,該如何進行完善那就是看個人的需求了。

返回目錄---->資料結構與演算法目錄

另外推薦讀者下面這篇部落格: 大牛

資源和**參考:

資料結構與演算法系列23 Trie樹

也叫 字典樹 根據它名稱,它本身就是乙個樹形結構。它是一種專門處理字串匹配的資料結構,用來解決在一組字串集合中快速查詢字串的問題。那trie樹究竟有何特殊之處呢,它是通過字串之間的公共字首,將重複的字首合併在一樣,並組織成一棵樹。舉個例子 我們現在維護有乙個字串庫,裡面存放了這樣有6個字串,他們分別...

資料結構與演算法 字典樹

字典樹又稱單詞查詢樹,trie樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計,排序和儲存大量的字串 但不僅限於字串 所以經常被搜尋引擎系統用於文字詞頻統計。它的優點是 利用字串的公共字首來減少查詢時間,最大限度地減少無謂的字串比較,查詢效率比雜湊樹高。字典樹 桀驁 2018 8 3 in...

資料結構與演算法系列19 堆

堆其實就是一種特殊的樹,那它特殊在 呢?只要滿足了以下兩點的,我們就可以稱之為堆。1.堆是乙個完全二叉樹 2.堆中每乙個節點的值都必須大於等於 或者小於等於 其子樹中每個節點的值。這裡稍作解釋,對於第一點,我們前面講過,完全二叉樹就是除了最後一層,其他層的節點個數都是滿的,最後一層的節點都靠左排列。...