初学字典树
字典樹又稱單詞查找樹,Trie樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用于統(tǒng)計,排序和保存大量的字符串(但不僅限于字符串),所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計。它的優(yōu)點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。
性質:
根節(jié)點不包含字符,除根節(jié)點外每一個節(jié)點都只包含一個字符; 從根節(jié)點到某一節(jié)點,路徑上經(jīng)過的字符連接起來,為該節(jié)點對應的字符串; 每個節(jié)點的所有子節(jié)點包含的字符都不相同。實現(xiàn)方法:
搜索字典項目的方法為: (1) 從根結點開始一次搜索; (2) 取得要查找關鍵詞的第一個字母,并根據(jù)該字母選擇對應的子樹并轉到該子樹繼續(xù)進行檢索; (3) 在相應的子樹上,取得要查找關鍵詞的第二個字母,并進一步選擇對應的子樹進行檢索。 (4) 迭代過程…… (5) 在某個結點處,關鍵詞的所有字母已被取出,則讀取附在該結點上的信息,即完成查找。 其他操作類似處理上面的樹就是一顆典型的字典樹了,字典樹中存儲的單詞包括:abc、abcd、abd、b、bcd、efg、hig,即:所有標記為紅心的是單詞的結尾字母。對比上面的trie樹的特點仔細看一下,理解一下到底什么是字典樹。實字典樹包括常見的兩種操作是:查找和插入操作,刪除不經(jīng)常用。
動態(tài)空間基本代碼:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef struct TrieNode{ //定義樹的節(jié)點存儲結構 int data; //可以表示一個字典樹到此有多少相同前綴的數(shù)目 struct TrieNode *next[26];TrieNode(){data=0;memset(next,0,sizeof(next));} };/*next是表示每層有多少種類的數(shù),如果只是小寫字母,26即可,若大小寫字母,則是52,若再加上數(shù)字,則是62了,這里根 據(jù)題意來確定。*/ TrieNode *root=NULL;//根節(jié)點要初始化 //建樹 void Build(char *c){TrieNode *p=root; //定義指針,指向根結點 TrieNode *q=NULL;int i,l=strlen(c);for(i=0;i<l;i++){if(p->next[c[i]-'a']==NULL){q=new TrieNode; //構造新節(jié)點 p->next[c[i]-'a']=q;}p=p->next[c[i]-'a'];p->data++;} } //查找 void Find(char *c){TrieNode *p=root;int i,l=strlen(c);for(i=0;i<l;i++){if(p->next[c[i]-'a']==NULL){printf("0\n");return;}p=p->next[c[i]-'a'];}printf("%d\n",p->data); } int main(){root=new TrieNode;.... return 0; }注意:
1.根節(jié)點要初始化:TrieNode *root=NULL; 2.有些題目,數(shù)據(jù)比較大,需要查詢完之后刪除、釋放內存;
刪除操作:
void Delate(TrieNode *root) {for(int i=0;i<N;i++)if(root->next[i])Delate(root->next[i]);delete(root); }例如:?NYOJ的http://http://acm.nyist.net/JudgeOnline/problem.php?pid=685查找字符串? 題解:http://blog.csdn.net/xwxcy/article/details/50116117靜態(tài)空間基本代碼:
這個代碼段數(shù)存放數(shù)字的,根據(jù)題意修個next[]; #include<iostream> #include<cstdio> #include<cstring> using namespace std; int data_TrieNode; struct TrieNode{int data;TrieNode *next[10];void init(){data=0;memset(next,0,sizeof(next));} }Tree[100001]; inline TrieNode *new_TrieNode(){ Tree[data_TrieNode].init(); return &Tree[data_TrieNode++]; } TrieNode *root=NULL; void Build(char *c){TrieNode *p=root;TrieNode *q=NULL;int i,v,l=strlen(c);for(i=0;i<l;i++){v=c[i]-'0';if(p->next[v]==NULL){q=new_TrieNode();p->next[v]=q;}p=p->next[v];p->data++;} } int Find(char *c){int i,v,l=strlen(c);TrieNode *p=root;for(i=0;i<l;i++){v=c[i]-'0';if(p->next[v]==NULL){return 0;break;}else p=p->next[v];}return p->data; } int main() { data_TrieNode=0;root=new_TrieNode();.... return 0; }總結
- 上一篇: 关于H5工程师那些日常必需工具
- 下一篇: 将Maven项目发布到Nexus私服