Trie樹(字典樹)整理

字典樹 (Trie)ide

用於存儲字符串。樹的每條邊剛好表示一個字符,每一個節點表明從根到該節點的路徑所對應的字符串。spa

簡介與操做實現可見藍書P82~83。3d

  Trie字典樹很好地利用了前綴,節省了不少空間。code

 1 //先說明一下:本代碼段的字符串d的下標都是從1開始
 2 inline void insert(char *d)//向Trie樹插入字符串d 
 3 {
 4     int l=strlen(d+1),now=0,num;
 5     for(int i=1;i<=l;++i)
 6     {
 7         num=d[i]-'a';//字符化爲數字下標 
 8         if(!tree[now][num])//當前節點不存在該字母的邊,即該字母還未在當前節點插入過 
 9             tree[now][num]=++cnt;
10         now=tree[now][num];
11     }
12     ed[now]=1;//最後標明一下字符串結尾節點,說明該節點表明了一個已插入過的字符串 
13 }
14 
15 inline int fin(char *d)從Trie樹查詢字符串d 
16 {
17     int  l=strlen(d+1),now=0,num;
18     for(int i=1;i<=l;++i)
19     {
20         num=d[i];
21         if(!tree[now][num])//不存在對應節點了,說明Trie中沒有這個串
22             return 0;
23         now=tree[now][num];
24     }
25     return ed[now];//查詢到最後還要看當前節點是否表明一個插入過Tire樹的字符串
26 }
操做實現的核心代碼

應用:blog

一、前綴查找。字符串

  在Trie樹中查找一個字符串的前綴。無論Trie樹中插入了多少個字符串,查找的複雜度都是優秀的O(n)(n爲當前字符串的長度)。event

  還有一種邊插邊找前綴的方法。若是當前串插入Trie樹時沒有新建任何節點,那它就是它的末尾節點的子樹中全部串的前綴;若是當前串插入Trie樹時通過了某個串x的末尾節點,那麼x就是當前串的一個前綴。class

二、異或相關。cli

  將每一個數看作二進制的01串。從Trie樹中找當前數字異或值最大的數,只要儘量向與當前邊反方向的邊走就好。bfc

 1 inline int fin(int a)//從Trie樹中找與a異或的結果最大的數,並返回這個結果
 2                      //a爲int範圍的一個正整數 
 3 {
 4     int ret=0,c,now=1;//這裏的Trie數根節點的編號爲1 
 5     for(int k=30;k>=0;--k)
 6     {
 7         if((a&(1<<k))^(1<<k))//看下a當前位取反的結果 
 8             c=1;
 9         else
10             c=0;
11         if(tree[now][c])//當前點能有a當前位表明邊的另外一側方向的邊的話,就走那條邊 
12         {
13             now=tree[now][c];
14             ret|=1<<k;//維護答案(當前走的與a的當前位不同的話,答案的當前位就是1,由於是異或) 
15         }
16         else//沒有的話,有哪條邊,就走那條邊嘍。
17             //Trie樹中至少有一個數的話,必定能一直走下去 
18             now=tree[now][c^1];
19     }
20     return ret;
21 }
相關代碼
相關文章
相關標籤/搜索