【模板】Trie樹模板
阿新 • • 發佈:2018-11-07
Trie樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計,排序和儲存大量的字元串(但不僅限於字串),所以經常被搜尋引擎系統用於文字詞頻統計。
上面是百度百科找的,trie樹=字典樹=字首樹,下面就說說字首樹的實現。
首先trie樹的根必定是一個空節點,每一條邊代表了一個字元,每一個節點有多種可能,那麼我們可以使用一個數組來達到這個目的;
同時,每一個單詞(字串)的最後一個字元所指向的節點需要做標記(如上圖的紅色節點),以表示從樹根到現在所遍歷的一個字串;
那麼上面所說的就可以通過一個結構體來實現。
然後這個trie就需要插入字串,刪除節點,以及查詢字串,當然,插入字串的函式或者搜尋字串也可以用來刪除某一字串;插入字串,從根節點開始,依次遍歷字串中的每一個字元,同時也建立新的節點,以達到插入的目的,下面是程式碼的實現:int num = 26; //以26個小寫字母為例 struct TrieNode { bool isTri; TrieNode *next[num]; };
void Insert(TrieNode* root,const char* word) { TrieNode *now = root; while(*word) { if(now->next[*word-'a']==NULL) //*word-'a'用於表示某一字元的位置 { TrieNode *newNode = new TrieNode(); newNode->isTri = false; newNode->yes = 0; memset(newNode->next,NULL,sizeof(newNode->next)); now->next[*word-'a'] = newNode; } now = now->next[*word-'a']; word++; } now->isTri = true; }
搜尋字串,也是從根節點開始,依次遍歷,直到樹的最深處或者到達字串的最後一個字元為止,在這個時候就可以如果到達數的最深處的時候字串仍然沒有遍歷完,或者遍歷完最後一個字元的時候這個加點未被標記,那麼我們就可以返回false的資訊,表示沒有搜尋到;反之,如果遍歷字串結束之後並且此時的節點被標記(儲存過該字串),則返回true的資訊,當然搜尋這裡還有部分的應用,這裡就不說了。
bool Search(TrieNode* root,const char* word) { TrieNode *now = root; while(*word) { if(*word&&now != NULL) { now = now->next[word-'a']; word++; } } return (now->isTri&&now!=NULL); }
刪除節點,就是使用遞迴的方式刪除節點,從某一節點開始,依次遍歷其所有節點,又繼續刪除;
void Delete(TrieNode* node)
{
for(int i = 0;i<num;i++)
{
if(node->next[i]!=NULL)
{
Delete(node->next[i]);
}
}
delete node;
}
完整程式碼:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int num = 26;
struct TrieNode
{
bool isTri;
TrieNode *next[num];
}
void Insert(TrieNode* root,const char* word)
{
TrieNode *now = root;
while(*word)
{
if(now->next[word-'a']==NULL)
{
TrieNode *newNode = new TrieNode();
newNode->isTri = false;
memset(newNode->next,NULL,memset(newNode->next));
now->next[word-'0'] = newNode;
}
now = *newNode;
word++;
}
now->isTri = true;
}
bool Search(TrieNode* root,const char* word)
{
TrieNode *now = root;
while(*word)
{
if(*word&&now != NULL)
{
now = now->next[word-'a'];
word++;
}
}
return (now->isTri&&now!=NULL);
}
void Delete(TrieNode* node)
{
for(int i = 0;i<num;i++)
{
if(node->next[i]!=NULL)
{
Delete(node->next[i]);
}
}
delete node;
}
int main()
{
TrieNode *root = new TrieNode();
root->isTri = false;
memset(root->next,NULL,sizeof(root->next));
//主函式就不寫了,這裡就是應用資料結構的地方,交代一下根節點的初始化即可
return 0;
}