字典树(Trie)的简单实现

本文详细介绍了字典树(Trie)的实现方法,包括节点结构定义、插入、查找及遍历等核心操作,并附带解释了递归遍历的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值