字典树(Trie树) C++实现
说明:
以下代码是个人按照自己的理解写的,可能有错误或者不太规范的地方,欢迎指出!
代码如下:
//插入、删除、查询、遍历四种操作 //注意:四种操作的函数实现中,T都是指向上一个结点的指针,以此方便操作。 #include<bits/stdc++.h> using namespace std; typedef long long LL; const double eps = 1e-6; const int INF = 2e9; const LL LNF = 9e18; const int mod = 1e9+7; const int maxn = 100+10; typedef struct node { bool exist; //是否存在单词 int cnt; //作为多少个单词的前缀,不算自己 struct node *next[26]; void init() { exist = cnt = 0; memset(next,0,sizeof(0)); } }Node, *Tree; void insert(Tree &T, char *s, int k) { if(!T) { T = new Node; T->init(); } if(!s[k]) //单词尾 { T->exist = true; //标记单词存在 } else { T->cnt++; //作为前缀 insert(T->next[s[k]-'a'], s, k+1); } } char ans[100]; //存储路径 void traverse(Tree T, int k) //字典序遍历,实际上就是先序遍历 { if(T->exist) //如果该节点标有单词编号,则输出路径 { ans[k] = 0; cout<<ans<<endl; } for(int i = 0; i<26; i++) { if(T->next[i]) { ans[k] = i+'a'; traverse(T->next[i], k+1); } } } int search(Tree T, char *s, int k) { if(!T) return 0; //结点不存在,则单词不存在 if(!s[k]) //结点存在,还要看单词是否存在 { return T->exist; } else //继续往下找 { return search(T->next[s[k]-'a'], s, k+1); } } bool del(Tree &T, char *s, int k) { if(!T) return 0; if(!s[k]) { if(T->cnt) //如果作为单词的前缀,则只标记此单词不存在 { T->exist = 0; } else //如果不作为其他单词的前缀,则直接删除 { delete T; T = NULL; } return 1; } else { if(del(T->next[s[k]-'a'], s, k+1)) { T->cnt--; if(!T->exist && !T->cnt) //既不作为单词的前缀,又不作为单词,则直接删除 { delete T; T = NULL; } return 1; } return 0; } } int main() { Tree T; T = new Node; T->init(); int n; cin>>n; char s[100]; for(int i = 1; i<=n; i++) { cin>>s; insert(T,s,0); } traverse(T,0); cin>>s; del(T,s,0); traverse(T,0); cin>>s; cout<< search(T,s,0) <<endl; }