数据结构-字典树

本文介绍了如何使用C++通过结构体和数组两种方式实现字典树的数据结构,并提供了插入和查询字符串的具体实现方法。

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

树节点

struct Node
{
	Node* next[MAX];//该结点的子节点
	int flag;
	Node()
	{
		for (int i = 0; i < MAX; i++)
		{
			flag = 0;
			next[i] = NULL;//将子结点都设置为空
		}
	}
};

通过字符串构造树

请添加图片描述

/*在字典树中插入一个字符串*/
void ins(string s)
{
	int len = s.size();//先获取字符的长度
	Node* now = root;//获取根节点
	/*从头开始遍历这个字符*/
	for (int i = 0; i < len; i++)
	{
		int to = s[i] - 'a';//就是一步步往后走
		if (now->next[to] == NULL)
		{
			now->next[to] = new Node();
		}
		now = now->next[to];

	}
}

数组实现

/*用数组实现字典树*/
#include<iostream>

using namespace std;

const int N = 1e7+5;
int son[N][26], cnt[N], idx;//son存当前点的所有儿子,cnt表示以当前点结尾的单词的个数,idx指向当前结点 他这里idx不初始化 因为是全局变量所以自动就是0
//下标是0 的点,既是根结点,又是空结点 
string str;
/*插入建树*/
void insert(string str)
{
	int p = 0;//根结点 
	for (int i = 0; str[i]; i++)
	{
		int u = str[i] - 'a';//把a~z映射成0~25的编号 
		if (!son[p][u]) son[p][u] = ++idx;//当前结点没有儿子就要建一条路  这个需要表示的其实就是一个结点 每一个idx都是一个结点序号 
		p = son[p][u];//else  p表示当前分支的最后一个点 
		/*这个p绝对别理解成层数了 p就是指向了某个结点   son[p][u]是他的下一个要指向的节点(就是比如你要找s 
		你就是在son[p]的子节点中找son[p][son-'a']就会告诉你s这个节点在哪 然后你获取他的值 你直接 p = 那个值就行了)
		而son[p]会存储好几个值 就是他的子结点 也就是他这个字母后面可能跟的字母*/
	}
	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];//else 继续 
	}

	return cnt[p];//以p结尾的单词数量,在插入操作时值已经确定 
}

图是别人那扒来的 如果侵权立刻删除
请添加图片描述
请添加图片描述
每一列实际上就是代表26个英文字母 竖行就是结点

第一张图是建dcba
第二张是在第一张图基础上deaf
建树都是这么建立 那我们就假设来搜索一下deaf吧
首先第一个就是d 此时p是0
那么就是搜索第一行son[p][‘d’-‘a’]找到了1 这个意思就是d这个节点是索引1的位置 然后此时p = 1 我们在1这一行中能看到 有两个结点 代表d后面跟着两种字母 再找e son[p][‘e’-‘a’]就会查到e是5这个节点 就跳去5
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值