导入
字典树是一种用于统计,排序和保存大量字符串的树形结构;它利用字符串的公共前缀来节省存储空间与缩短查询时间。字典树中字符并不保存在树的节点上而是保存在边上,从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。下面是一颗字典树的例子:
输入单词:as、bad、book、books、boot、cat、car、 cargo、cap,构建字典树如下:

字典树的实现
为方便在竞赛、笔试编程题中使用trie,这里介绍一种简单的用数组实现的方式。
定义二维int数组node[u][i],表示结点u的第i个字符指针指向的结点,i所指代的字符指针可以自定义,如1表示a,2表示b,······,26表示z,27表示A,······,52表示Z等等。
再定义bool数组isEnd[u],若为true则表示结点u是一个字符串的结尾。例如上图中绿色结点的isEnd均为true,而白色结点的isEnd均为false。
向Trie中插入一个字符串:
char node[N][Z];
bool isEnd[N];
int size=0;
//插入单词
void insert(char *s){
int len=strlen(s);
int u=1;//从根结点开始
for(int i=0;i<len;++i){
int c=s[i]-'a'; //这里只能插入小写字符,想要插入其它字符需要修改
if(!node[u][c])//如果子结点不存在,就新建一个结点
node[u][c]=++size;//新结点添加到数组的末尾
u=node[u][c]; //指针指向子结点
}
isEnd[u]=true;
}
查询单词是否存在 :
bool find(char *s){
int len=strlen(s);
int u=1;//从根结点开始
for(int i=0;i<len;++i){
int c=s[i]-'a';
if(!node[u][c])//如果子结点不存在,说明该单词不存在
return false;
u=node[u][c];
}
if(isEnd[u]) return true;
return false;//如果最终到达的结点不能作为字符串的结尾,则该单词还是不存在,只是某一单词的前缀
}
查询字符串是否是某一单词的前缀 :
bool find_prefix(char *s){
int len=strlen(s);
int u=1;//从根结点开始
for(int i=0;i<len;++i){
int c=s[i]-'a';
if(!node[u][c])//如果子结点不存在,说明该字符串不是某一单词的前缀
return false;
u=node[u][c];
}
return true;
}

1170

被折叠的 条评论
为什么被折叠?



