当前位置: 首页 > news >正文

高阶数据结构 --- Trie 树

大家好,我们又见面了。这一期,我来给大家介绍一个高阶数据结构:Trie 树。

字典树在计算机领域还是非常常见的,相信这篇文章一定会对大家有所帮助。

创作不易!!!别忘了一键三连~~~

废话不多说,我们直接开启这一期的内容。

一:字典树的概念

Trie 树又叫字典树前缀树,是一种能够快速处理插入和查询字符串的数据结构。它利用字符串的公共前缀,将字符串组织成一颗树形结构,从而大大提高了存储以及查询的效率。

注:哈希表和红黑树也可以做到快速处理插入和查询字符串的操作。但这并不能说明字典树的设计是多余的,字典树可以做到一些它们做不到的事情。

我们可以把字典树想象成为一颗多叉树,其中每一条边代表一个字符从根节点到某个节点的路径就代表了一个字符串。例如,要存储 "abc" "abd" "acde" 以及 "cd" 时,构建的字典树如下:

上述字典树构建过程:(自己多模拟几遍)

1. 一个字符串一个字符串遍历,当遍历到某一个字符串时,遍历它的每一个字符。

2. 第一个字符对应树的第一二层之间的边,第二个字符对应树的第二三层之间的边,依次类推。

3. 初始状态下,字典树只有一个根节点(第一层)。

2. 从根节点开始,如果有对应这一个字符的路径,就复用,走下去,如果没有,就创建路径。

这样创建完毕之后,处理查询字符串的逻辑也与插入字符串类似。一层一层往下走。

比如:查询字符串 "acde" "ad" ,一层一层往下走,发现 "acde" 存在,"ad" 并不存在。

自己下去模拟,详细过程这里不赘述了。

但是按照上面方式创建出的字典树是有一定问题的。比如:

1. 我们我们想要查询字符串 "ac" 是否存在,按照上述方式是会判断它存在的,但是实际并没有插入 "ac" 字符串。

2. 再比如,如果我们之前插入了 "acde",现在又要插入 "ac",这时实际就存在 "ac" 字符串了。

3. 再比如,如果我们插入了很多个 "ac" 字符串,查询的时候怎么才能知道插入了多少个呢???

基于上述问题,我们在字典树的每一个结点上多维护两个变量:

1. pass:标记当前结点一共出现 / 经过了多少次。

2. end:标记当前结点是以多少个字符串为结尾。

然后我们在插入字符串的同时维护好每一个节点的信息,就可以解决上面的问题了。

这样的话,就很好的解决了上面的问题。

二:字典树的作用

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

1. 查询某一个单词是否出现过,并且出现过几次。

2. 查询有多少个单词是以某一个字符串为前缀。

3. 查询所有以某个前缀开头的单词。(dfs 子树)

三:字典树的模拟实现

我们实现一个能够查询某单词出现次数以及查询有多少个单词是以某个字符串为前缀的字典树。

默认全是小写字母 a~z:

1. 准备工作

#include <iostream>
#include <cstring>using namespace std;
const int N = 1e6 + 10;int tree[N][26], p[N], e[N];
int idx;

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:新来一个字符之后,为它分配位置。

接下来通过一张图深刻理解一下 tree 数组的作用:

2. 插入字符串

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]++; // 维护节点的 pass 信息}e[cur]++; // 最后别忘了维护 e 信息
}

3. 查询字符串出现的次数

int find(string& s)
{int cur = 0; // 从根节点开始for (auto ch : s){int path = ch - '0'; // 路径编号if (tree[cur][path] == 0) return 0; // 没有路,找不到cur = tree[cur][path]; // 走下去}return e[cur]; // 找到了,返回出现的次数
}

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

int find_pre(string& s)
{int cur = 0;for (auto ch : s){int path = ch - '0';if (tree[cur][path] == 0) return 0;cur = tree[cur][path];}return p[cur];
}

建议:一定要下去之后自己多找几个字符串模拟几遍,只要明白了原理,代码是很简单的。

好的,这一期的分享就到这里了,我们下一期再见。

http://www.dtcms.com/a/491714.html

相关文章:

  • PCIe协议之 flit 模式 之 flit bytes placing 图示说明
  • 如何做网站大管家Apple 手机网站制作
  • Unity 导出 AAR包 到 Android 项目并以 Fragment渲染显示
  • 把 AI“种”进闪存:基于极值量化与分块蒸馏的 7B 大模型 U 盘部署实战
  • 中兴电信B860AV3.2-T/B860AV3.1-T2(S905L3SB)2+8G_安卓9.0_线刷固件包
  • 网站建设主要工作内容动漫制作专业一定要艺术生吗
  • .livp,.HEIC格式图片转换成jpg格式图片
  • NewStarCTF2025-Week1-Web
  • 网站根目录 本地共享阿里指数在哪里看
  • 浏阳市商务局网站溪江农贸市场建设有什么平台可以发广告
  • FPGA强化-VGA显示设计与验证
  • 【2025最新】ArcGIS for JavaScript 快速实现热力图渲染
  • 怎么设置网站的logowordpress通知邮件美化
  • SpringCloud-Gateway实战使用与深度源码分析
  • 上海网站建设|网站制作浙江新手网络推广
  • 健康管理实训室厂家报价:精准明细,按需提供
  • Git学习笔记(三)
  • 通达信组合平台
  • 怎么做微网站推广泉州建设银行网站
  • 企业网站形象建设企业申请完域名以后 怎么把网站运行起来
  • 序列的力量——Python 内置方法的魔法解密
  • 跨数据源操作
  • 数据库圣经——第三章CRUD(一)
  • 信创学习小手册【第一天】
  • 动漫网站建设规划书模板制作网站主要包括哪些步骤
  • 基于Vue社区共享游泳馆预约系统n897q36e (程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • PyTorch Dataloader工作原理 之 default collate_fn操作
  • 2022年英语笔记
  • 东莞市的网站公司哪家好shopnc
  • 建站工具上市家居网站建设行业现状