字典树(Trie)的简单实现

来源:互联网 发布:在线网络理财规划 编辑:程序博客网 时间:2024/05/17 02:49

需要用到的库和头文件如上

#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; } 

我觉得主要是遍历那个递归比较难理解,手动模拟一次就明白了

0 0