Trie 树也叫字典树,是一种用于快速检索的多叉树结构。如英文字母的字典树 是 一个 26 叉树。数字的字典树是一个 10 叉树。Trie 树把要查找的关键词看作 一个字符序列,并根据构成关键词字符的先后顺序构造用于检索的树结构;一棵 m 度的 Trie 树或者为空,或者由 m 棵 m 度的 Trie 树构成。特别的:和二叉查找 树不同,在 Trie 树中,每个结点上并非存储一个元素。在 Trie 树中查找 一个 关键字的时间和树中包含的结点数无关,而取决于组成关键字的字符数。 特点: ①利用串的公共前缀->节约内存。 ②根结点(root)不包含任何字母。 ③其余结点仅包含一个字母(非元素)。 ④每个结点的子结点包含字母不同。 查找过程: ①在 Trie 树上进行检索总是始于根结点。 ②取得要查找关键词的第一个字母, 并根据该字母选择对应的子树并转到该子树 继续进行检索。 ③在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树 进行检索。 ④在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即 完成查找。 其中 STL 中可直接调用 map(强大的 map 函数,acmer); #include #include #include using namespace std; int main() { string a,b; int i,len; mapm; cin>>a; while(cin>>a,a!="END") { cin>>b; m[b]=a; } cin>>a; getchar(); char s[3002]; while(1) { gets(s); len=strlen(s); if(strcmp(s,"END")==0) break; s[len]='\n'; b=""; for(i=0;i<=len;i++) { if(s[i]>='a'&&s[i]<='z') { b+=s[i]; } else { if(m[b]!="") cout< using namespace std; ; const int MAXM = 30,KIND = 26; , ; int m; ; struct node { char* ; char* s; int prefix; ; bool isword; ; node* next[KIND]; * [ ]; node() () { s = NULL; ; prefix = 0; ; isword = false; ; memset(next,0,sizeof(next)); ( , ,sizeof( )); } }*root;//根 }* ; void insert(node *root,char *s)//插入 ( , ) { node *p = root; ; ];i++) for (int i = 0;s[i]; ++) ; [ ]; { int x = s[i] - 'a'; [ ] ; p->s = s+i; + ; if (p->next[x] == NULL) [ ] ) p->next[x] = new node; [ ] ; p = p->next[x]; [ ]; p->prefix++; ++; } p->isword = true; ; } ( , ) bool del(node *root,char *s)//删除 { node *p = root; ; ];i++) for (int i = 0;s[i]; ++) ; [ ]; { int x = s[i] - 'a'; [ ] ; if (p->next[x] == NULL) [ ] ) return false; ; p = p->next[x]; [ ]; } if (p->isword) ) p->isword = false; ; else return false; ; return true; ; } bool search(node *root,char* s)//查找 ( ,char* ) { node* p = root; * ; ];i++) for (int i = 0;s[i]; ++) ; [ ]; { int x = s[i]-'a'; [ ] ; if (p->next[x] == NULL) [ ] ) return false; ; p = p->next[x]; [ ]; } return p->isword; ; } int count(node *root,char *s)//统计后缀 ( , ) { node *p = root; ; ];i++) for (int i = 0;s[i]; ++) ; [ ]; { int x = s[i] - 'a'; [ ] ; [ ] ) if (p->next[x] == NULL) return 0; ; p = p->next[x]; [ ]; } return p->prefix; ; } main() int main() { m = 0; ; root = new node; ; [ ]; char s[MAXM]; while (gets(s)) ( )) { if (strcmp(s,"") == 0) ( , ) ) break; break; insert(root,s); ( , ); } while (gets(s)) ( )) printf("%d\n",count(root,s)); ( , ( , )); } 静态: #include using namespace std; ; const int MAXN=10010,MAXM=30,kind=26; = , = , = ; int m; ; struct node { char *s; ; int count; ; bool isword; ; node *next[kind]; [ ]; void init() () { s=NULL; = ; count=0; = ; isword=false; = ; memset(next,0,sizeof(next)); ( , ,sizeof( )); } ],*root; [ * ],* ; }a[MAXN*MAXM],* void insert(node *root,char *s) ( , ) { int i,index; , ; node *p=root; = ; for( = ; [ ]; ];i++) for(i=0;s[i]; ++) { index=s[i]-'a'; = [ ] ; p->s=s+i; - = + ; ]==NULL) if( [ ]== ) if(p->next[index]== { a[m]. ].init(); [ ]. (); p->next[index]=& [m++]; ]=&a[ ++]; [ ]=& } p=p->next[index]; = [ ]; p->count++; ++; } p->isword=true; = ; } bool del(node *root,char *s) ( , ) { node *p=root; = ; int i,index; , ; ];i++) for( = ; [ ]; for(i=0;s[i]; ++) { index=s[i]-'a'; = [ ] ; if( ]==NULL) if(p->next[index]== [ ]== ) return false; ; p=p->next[index]; = [ ]; } if( if(p->isword) ) p->isword=false; = ; else return false; ; return true; ; } bool search(node *root,char *s) ( , ) { node *p=root; = ; int i,index; , ; for( = ; [ ]; ];i++) for(i=0;s[i]; ++) { index=s[i]-'a'; = [ ] ; if( ]==NULL) if(p->next[index]== [ ]== ) ; return false; p=p->next[index]; = [ ]; } ; return p->isword; } int count(node *root,char *s) ( , ) { node *p=root; = ; int i,index; , ; ];i++) for( = ; [ ]; for(i=0;s[i]; ++) { index=s[i]-'a'; = [ ] ; if( ]==NULL) if(p->next[index]== [ ]== ) return 0; ; p=p->next[index]; = [ ]; } return p->count; ; } main() int main() { int m=0; = ; a[m]. ].init(); [ ]. (); root=& [m++]; =&a[ ++]; =& char s[MAXM]; [ ]; while( while(gets(s)) ( )) { if( )==0) if(strcmp(s,"")== ) ( , )== break; break; insert(root,s); ( , ); } while( while(gets(s)) ( )) printf("%d\n",search(root,s)); ( , ( , )); return 0; ; }