字典樹,顧名思義,就是把字典放到樹上ui
不不不,是用字典來建樹spa
把樹建成字典的樣子?指針
差很少。code
字典樹指的是某個字符串集合對應的有根樹,樹的每條邊上剛好對應一個字符,每一個頂點表明從根到該節點的路徑所對應的字符串(將全部通過的邊上的字符按照順序鏈接起來)。有時咱們也稱trie上的邊爲轉移,節點爲狀態blog
是否是讀起來很噁心?字符串
其實能夠這麼理解string
字典樹就是一棵利用了字符串的公共前綴(好比gcakioi和gcakimo的前綴就是gcaki)來減小查詢時間的樹。當你查詢單詞的時候,只要沿着轉移邊查找就能夠了,而且對於每一個單詞的結尾,在字典樹上都會有標記來表示這是一整個單詞。io
舉個例子class
如今有兩個單詞gc
A:GCAKIOI
B:GCAKIMO
那麼這個字典樹大概就是這個樣子
很是直觀對吧
就是在相同的時候合到一塊兒,不一樣的時候分開,在單詞結尾進行標記就行了
操做實現:
1.初始化
一棵空的trie只包含一個根節點,該點的字符指針都指向空
int ch[N][Z]//Z爲字符集大小,ch[i][j]表示節點i的j字符指向的節點 bool bo[N]//對給以i爲終止字符的節點打標記
2.插入
當須要插入一個字符串S的時候,咱們令一個指針P指向根節點,而後依次掃描S中的每一個字符c
inline void build(string s,int id) { int now=1,len=s.size(); rep(i,0,len-1) { int c=s[i]-'a'; if(!ch[now][c]) { ch[now][c]=++cnt; }//若是尚未這個節點,就新建立一個節點 now=ch[now][c];//當前節點轉移過去 } bo[now]=id;//給以節點now爲終止節點的打上標記 }
3.查詢
當咱們要查詢一個字符串S在trie中是否出現時,咱們令一個指針P起初指向根節點,而後依次掃描S中的每個字符c
inline bool find(char s[]) { int now=1,len=strlen(s),c,k; rep(i,0,len-1)//在字典樹上查找該單詞 { c=s[i]-'a'; if(!ch[now][c]) return false; now=ch[now][c]; } return true; }
當字符均爲小寫字母或者大寫字母時,trie能夠當作一個26叉樹
它的空間複雜度爲O(N*C),N是節點個數,C是字符集的大小