学习笔记7||数据结构|用数组实现trie树

本文介绍了使用数组实现Trie树的方法,详细分析了插入和查找过程。在插入过程中,通过循环读取字符串并更新节点,确保每个字符对应的儿子节点正确创建。查找过程中,根据已有的节点判断字符串是否存在。Trie树对于快速查询和存储字符串集合非常有效。

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

trie的作用是快速的查询和存储字符串集合。实现就是根节点之后查询字符有就继续没有就增加。同时标记结尾。
存储和查找示意图:
在这里插入图片描述

实现

#include<iostream>
using namesapce std;
const int N=100010;
int son[N][26],cnt[N],idx;
char str[N];
//插入函数
viod insert(char str[ ]){
int p=0;
for(int i=0;str[i];i++]){//str[]的结尾是/0
int u=str[i]-'a';//0~25把字母转换成数字,u现在存放的是插入的字符
if(!son[p][u]) son[p][u]=++idx;//如果没有就创建,在这一层
p=son[p][u];
}
cnt[p]++;
}
//查找过程
int query(char str[]){
int p=0;
for(int i=0;str[i];i++){
int u=str[i]-'a';
if(!son[p][u]) return 0;
p=son[p][u];
}
return cnt[p];
}
int main(){
//主函数
}

idx中存储当前用到了那个节点。son[x ] 中存储的是儿子们,cnt中存储的是以x为结尾的点的个数。

分析插入过程

son这个二维数组之中存储的就是tire数中所包含的字符串,在插入的函数中,首先就是循环读入字符串,要是不存在这个字符的话就加上,idx表示的是当前使用的节点,就是已经是第几个儿子了,要是没有的话就添加,比如一开始是一个空的树,现在要在这个树中加入abc,先进行循环,读入a字符,a字符是不存在的,因此进入了if条件判断,这个时候idx首先是+1变成1;赋值给son[0][a](a这个时候已经转化成相应的数字,这里写a是为了更加的直观),然后p=1,进行下一个循环,读入字符b,b也是不存在的,就进入if的条件判断,son[1][b]=2;出来之后再更新p的值,p=2;在进行循环读入字符c,同样son[2][c]=3;p=3; 读入结束,此时son中存储完第一个单词,son[0][a]=1;son[1][b]=2;son=[2][c]=3; cnt[3]=1接下来进行插入ab的话,首先进行循环的读入,a读入之后,son[0][a]是存在的,因此不进入if的条件判断,p=son[0][a]=1;同理b读入之后son[1][b]=2;cnt[2]=1;
这样就完成了操作。从上述过程分析可知idx中更新的是第几个儿子。

分析查找过程

同样的,要是不存在直接返回0,要是存在的话就把自己是第几个儿子赋值给p,最终判断p是不是一个结尾就行了。

#include<iostream>
#include<cstring>

using namespace std;

const int N=100010;
int son[N][26],cnt[N],idx;//cnt以当前这个结尾的有多少个,下标是0的点,既是根节点又是空节点
char str[N];
void insert(char str[]){
    int p=0;
    for(int i=0;str[i];i++){
        int u=str[i]-'a';
        if(!son[p][u])son[p][u]=++idx;//有的话就继续,要是没有的话就加入。
        p=son[p][u];
    }
    cnt[p]++;
}
int query(char str[])
{
    int p=0;//每次的都从头开始寻找
    for(int i=0;str[i];i++) {
        int u=str[i]-'a';
        if(!son[p][u]) return 0;
        p=son[p][u];//在此处把p更新成了自己的儿子
    }
    return cnt[p];
}
int main(){
    int n;
    scanf("%d",&n);
    while(n--){
        char op[2];
        scanf("%s%s",op,str);
        if(op[0]=='I') insert(str);
        else printf("%d\n",query(str));
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值