算法基础篇(12)Trie树

1、字典树的概念

Trie树,又称为字典树 或者前缀树,是一种能够快速插入和查询字符串的数据结构。可能有人会问:在C++中,我们可以用哈希表unordered_map<string, int>来同样实现这一效果,那么为什么要使用字典树呢?其实,Trie树可以做到哈希表做不到的事情,我们接着往后看。

它利用字符串的公共前缀,将字符串组织成一个树结构,从而大大提高了存储以及查找效率。我们可以把字典树想象成一棵多叉树,每一条边代表一个字符,从根节点到某个节点的路径就代表了一个字符串。

比如,我们现在要存储"abc"这一字符串,我们先从第一个节点开始,如果没有a这条边,我们就创建一条边,然后把字符a存储在这条边上,以此类推。接着存储"abd",我们发现,a这条边在之前已经创建过了,所以我们可以直接复用这条边即可。同理,接下来b这条边也可以继续复用,最后只需要把d这条边创建出来即可。同理,也可以存储"acde"和"cd"。最后就形成这样一颗树:

但是这样简单存储的话,会带来一个问题。比如现在我们要查询"ac"这个字符串是否存在,我们访问这棵树的话,会找到ac这条路径,但事实上,这只是acde的前缀而已,我们之前并没有存储过ac这个字符串。所以,我们需要额外创建两个变量来维护信息。一个是pass:标记当前节点一共经过了多少次 ;另一个是end:标记当前字符串是以多少个字符串为结尾。此时构建出的字典树如下:

2、字典树的作用

当我们在字典树的每一个节点位置,额外维护一些信息时,就可以做到很多事情:

·查询某个单词是否出现过,并且出现几次

·查询有多少个单词是以某个字符串为前缀(这点就是哈希表做不到的)

·查询所有以某个前缀开头的单词(这个作用可以运用到输入法中,输入拼音时可以提示可能出现的词)

当然,除了上述作用以外,字典树还可以解决别的问题,后续在做题中慢慢体会。

3、字典树的实现

实现一个能够查询单词出现次数 以及查询有多少个单词是以某个字符串为前缀的字典树,默认全是小写字母。

准备工作:

cpp 复制代码
#include <iostream>
#include <cstring>
using namespace std;

const int N = 1e6 + 10;  // N表示所有字符串中一共有多少个字符

// tree[i]表示i号节点的孩子信息
// tree[i][0]表示'a'的路径信息
// tree[i][1]表示'b'的路径信息
// tree[i][2]表示'c'的路径信息
// p[i]表示i号结点的pass信息
// e[i]表示i号结点的end信息
// idx表示新来一个字符之后,为它分配位置
int tree[N][26], p[N], e[N];
int idx; 

插入字符串:

cpp 复制代码
void insert(string& s)
{
	int cur = 0;
	p[cur]++;
	
	for(auto ch : s)
	{
		int path = ch - 'a';
		if(tree[cur][path] == 0)
			tree[cur][path] = ++idx;
			
		cur = tree[cur][path];
		p[cur]++;
	}
	e[cur]++;
}

查询字符串出现的次数:

cpp 复制代码
int find(string& s)
{
	int cur = 0;
	for(auto ch : s)
	{
		int path = ch - 'a';
		if(tree[cur][path] == 0)
			return 0;
			
		cur = tree[cur][path];
	}
	return e[cur];
}

查询有多少个单词以字符串s为前缀:

cpp 复制代码
int find_pre(string& s)
{
	int cur = 0;
	for(auto ch : s)
	{
		int path = ch - 'a';
		if(tree[cur][path] == 0)
			return 0;
			
		cur = tree[cur][path];
	}
	return p[cur];
}
相关推荐
GreenTea8 小时前
vLLM 与 SGLang KV Cache 底层实现机制深度调研报告
前端·后端·算法
Bode_20028 小时前
多资源规划(含生产调度、库存管理及产能规划)的创新优化算法
算法·调度
土司大王9 小时前
LeetCode hot100——35.搜索插入位置:Java 二分模板、左闭右开区间与插入点分析
java·算法·leetcode
微三云生态系统架构师-彭丹9 小时前
远方好物S2B2C系统架构:一级分销与保证金托管的合规技术实现
人工智能·算法
土司大王9 小时前
LeetCode hot100——34.在排序数组中查找元素的第一个和最后一个位置:Java 二分模板、边界分析
java·算法·leetcode
罗西的思考11 小时前
机器人模型(WM / WAM / VLA)综合分析与对比:从「看」到「想」再到「做」
人工智能·算法·机器学习
小哈里12 小时前
【知识】从学科到实践:自然・工程・社科・人文|算法・研发・产品・品牌设计
程序人生·算法·产品·设计·工程
小π军12 小时前
最大重叠区间数量
数据结构·算法
镜像视界(浙江)科技有限公司13 小时前
《视频孪生之上:二维展示终结,三维空间计算重构城市逻辑》——跨摄像连续表达 × 三角测量厘米级定位 × 动态轨迹建模,构建新一代城市空间
大数据·人工智能·算法·矩阵·音视频·空间计算
a1879272183113 小时前
【算法】双指针与滑动窗口(二):滑动窗口——吃进、判定、吐出
算法·leetcode·双指针·滑动窗口·原理·模板·算法讲解