1. 程式人生 > 實用技巧 >Trie 樹

Trie 樹

Trie 樹

踹樹 那麼 踹樹 Trie 樹是什麼?

字典樹,又稱單詞查詢樹,Trie樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計,排序和儲存大量的字串(但不僅限於字串),所以經常被搜尋引擎系統用於文字詞頻統計。它的優點是:利用字串的公共字首來減少查詢時間,最大限度地減少無謂的字串比較,查詢效率比雜湊樹高。 —— 某度某科 在電腦科學中,Trie,又稱字首樹或字典樹,是一種有序樹,用於儲存關聯陣列,其中的鍵通常是字串。與二叉查詢樹不同,鍵不是直接儲存在節點中,而是由節點在樹中的位置決定。一個節點的所有子孫都有相同的字首,也就是這個節點對應的字串,而根節點對應空字串。一般情況下,不是所有的節點都有對應的值,只有葉子節點和部分內部節點所對應的鍵才有相關的值。 —— 維基百科

從上面可以看出,Trie 樹是用來做字串查詢題的

Trie 樹是一種典型的 用空間換時間的演算法 它快,是因為單詞之間擁有公共字首

來看一張我畫的圖:

從根節點開始,每個節點都最多 有26個分支,也就是說,Trie 樹是一個26叉樹。 那麼圖中有幾個單詞呢? ——4個,分別是ab,b,zc,zd。 標紅點代表有一個單詞。

怎樣插入單詞呢?

我們要插入一個單詞,需要逐位分析。

比如插入單詞 bc。 從根節點出發,發現當前有第一個字母b,繼續找 第二個字母 c,發現當前沒有 c,於是新建一條。 因為這是單詞末尾,所以打上標記 => 紅色。

於是,我們就可以踹樹了(手動滑稽)

建立:

struct node{
int ch[26];
bool have;
}t[800000];

插入

int num = 0;
void insert(string s){
int u=0,len=s.size();
for(int i=0;i<len;i++){
int v=s[i]-'a';//統一大小寫
if(!t[u].ch[v]){
t[u].ch[v]=++num;
}
u=t[u].ch[v];
}
t[u].have=true;//打標記
return ;
}

查詢

再放一下圖

假如我們現在要查 zc 這個單詞。 從根出發,有節點 z,那麼順著這條向下走。 有節點 c 。因為 c 是最後一位,所以檢視這裡的標記——有標記。說明有 zc 這個單詞。 而查詢 bc 的時候,b 下面沒有 c,所以沒有 bc 。

int query(string s){
int u=0,len=s.size();
for(int i=0;i<len;i++){
int v=s[i]-'a';
if(!t[u].ch[v]) return false;//沒有單詞,直接返回false
u=t[u].ch[v];
}
return t[u].have;//如果有標記,返回true,否則false;
}

踹樹真好

Trie 樹在字串方面運用的很廣泛,一般來說,主要運用於字串的儲存。AC自動機就是使用 Trie 樹來儲存的。