需要用到的库和头文件如上
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 256
每一个节点的结构,由一个count和指向下一个节点的指针构成
Tip:事实上,一个结构体包含了256个指针,为了避免繁琐,直接简化理解成只有一个指针
typedef struct trienode
{
int count;
struct trienode *next[MAX];
}trienode;
插入一个节点
void insert(char *ch,trienode *root)//传入单词地址以及根节点位置
{
int i=0;
trienode *cur=root;//创建一个指针,地址和根节点相同
while(ch[i]!='\0')
{
if(cur->next[ch[i]]==NULL)//如果下一个节点还没有创建
{
trienode* newtrie=(trienode *)malloc(sizeof(trienode));//先新创一个这样的结构体
memset(newtrie,0,sizeof(trienode));//归零一下
cur->next[ch[i]]=newtrie;//把这个节点包含的指针指向新创的结构体,形成了关联
}
cur=cur->next[ch[i]];//这个cur指针也得移到下一个节点
i++;//为读取下一个字母作准备
}
cur->count++;//单词读完以后,在结尾做个标记
}
查找一个单词
int find(char *ch,trienode *root)
{ int i=0;
trienode *cur=root;//还是创建一个指针
while(ch[i]!='\0')
{
if(cur->next[ch[i]]==NULL)//如果这个单词创建过,这里的指针就应该指向下一个地址,不然就是NULL
return 0;
else
cur=cur->next[ch[i]];//发现有的话我们继续往下找
i++;
}
if(cur->count>0)//结尾这里有标记,检验下
return 1;
}
遍历字典树
void traverse (trienode *cur)
{
static char word[MAX];//初始化一次,遍历全程使用
static int pos=0;//同上
int i;
if(cur==NULL)//递归的初始条件
return;
if(cur->count>0)//递归的初始条件
{
word[pos]='\0';
while(cur->count--)//这个count用完就丢了...需要遍历多次的话另作循环吧
printf("%s\n",word);
}
for(i=0;i<MAX;i++)//开始循环搜索
{
word[pos]=i;//先认定节点是存在的
pos++;//不然的话递归开始后我怎么把字母一个个保存进去
traverse(cur->next[i]);//进入下一个指针搜索
pos--;//递归结束回来后pos要变回来,因为递归完只是一次,我还要反复用pos来搜索剩下的值
}
}
主程序
太简单不写了
int main ()
{
trienode *root;
root=(trienode *)malloc(sizeof(trienode));
memset(root,0,sizeof(trienode));
int exam,make;
char ch[MAX];
scanf("%d",&exam);
while(exam--)
{
scanf("%s",ch);
insert(ch,root);
}
scanf("%d",&make);
while(make==1){
scanf("%s",ch);
if(find(ch,root))
printf("Yes\n");
else
printf("No\n");
scanf("%d",&make);
}
traverse(root);
return 0;
}
我觉得主要是遍历那个递归比较难理解,手动模拟一次就明白了