首页 > 代码库 > Trie树(字典树) 个人模版
Trie树(字典树) 个人模版
Trie树的基本实现
字母树的插入(Insert)、删除( Delete)和查找(Find)都非常简单,用一个一重循环即可,即第i 次循环找到前i 个字母所对应的子树,然后进行相应的操作。实现这棵字母树,我们用最常见的数组保存(静态开辟内存)即可,当然也可以开动态的指针类型(动态开辟内存)。至于结点对儿子的指向,一般有三种方法:
1、对每个结点开一个字母集大小的数组,对应的下标是儿子所表示的字母,内容则是这个儿子对应在大数组上的位置,即标号;
2、对每个结点挂一个链表,按一定顺序记录每个儿子是谁;
3、使用左儿子右兄弟表示法记录这棵树。
三种方法,各有特点。第一种易实现,但实际的空间要求较大;第二种,较易实现,空间要求相对较小,但比较费时;第三种,空间要求最小,但相对费时且不易写。
这里采用第一种,速度较快,适合ACM竞赛。
孩子数组大小自定义,此处默认为字母数26;
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath> using namespace std; typedef struct Trie { int nCount; //该节点前缀 出现的次数 struct Trie *next[26]; //孩子结点 }Trie; Trie Memory[1000000]; //先分配内存 malloc费时间 int allocp = 0; //初始化节点。nCount计数为1,next都是为NULL Trie * InitNode() { Trie * tmp = &Memory[allocp++]; tmp->nCount = 1; for(int i=0;i<26;i++) tmp->next[i]=NULL; return tmp; } void insertTrie(Trie * * pRoot, char * str) { Trie * tmp = *pRoot; int i=0,k; //逐个插入 while(str[i]) { k=str[i]-'a'; if(tmp->next[k]) { tmp->next[k]->nCount++; }else { tmp->next[k]=InitNode(); } tmp = tmp->next[k]; i++; } } int searchTrie(Trie *root,char *str) { if(root==NULL) return 0; Trie *tmp = root; int i=0,k; while(str[i]) { k=str[i]-'a'; if(tmp->next[k]) { tmp = tmp->next[k]; }else { return 0; } i++; } return tmp->nCount; //返回最后那个结点保存的ncount } int main() { int m,n; char s[11]; Trie * root = InitNode(); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%s",s); insertTrie(&root,s); } scanf("%d",&m); for(int i=0;i<m;i++) { scanf("%s",s); printf("%d\n",searchTrie(root,s)); } return 0; }
Trie树(字典树) 个人模版
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。