Trie 树构造原理、应用场景与复杂度分析
Trie 树构造原理
字典树,又称 Trie 树,是一种专门用于字符串匹配的树形结构,能够高效的在一组字符串中寻找所求字符串,与红黑树,散列表类似,但是又有其优势。
如何构造一颗 Trie 树
假设我们有一组字符串:abc
,adf
,adrf
,siab
。
Trie 树的本质,就是利用字符串之间的公共前缀,将重复的前缀合并在一起。如图:
根节点不包含任何信息,从根节点一路往下到灰色节点,便是一个字符串。
注意:灰色节点并不一定是叶子节点,当字符串组中存在abc
,abcdfg
这样的时,前者是后者的前缀,为了区分是两个字符串,需要给每个字符串的结尾字符做标记。
在Trie树中查找
假设我们要查找abf
,先将其拆分成 单个字符,按照下图路径,一层一层比较查找。直到最后一个字符恰好存在并且是灰色节点。
如何构造一颗 Trie 树
上述分析可知,字典树是一颗多叉树,二叉树中是通过左右子节点指针实现的,那么多叉树该如何实现呢?
//二叉树
class BinaryTreeNode{char data;BinaryTreeNode left;//左子节点BinaryTreeNode right;//右子节点
}
假设当前字符串只包含a-z
26 个字符,那么可以使用 26 个单位的子节点数组来实现:
class TriaTree{char data;bool isEndingChar;TriaTree node[26];
}
//字典树单个节点类
public class TriaTree {public char data;//数据域public TriaTree[] children = new TriaTree[26];//指向下一个字符public boolean isEndingChar = false;//是否为某个字符串结尾字符public TriaTree(char data) {this.data = data;}
}
public class Trie {private TriaTree root = new TriaTree('/'); // 存储无意义字符// 往 Trie 树中插入一个字符串public void insert(char[] str) {TriaTree p = root;for (int i = 0; i < str.length; ++i) {int index = str[i] - 'a';if (p.children[index] == null) {TriaTree newNode = new TriaTree(text[i]);p.children[index] = newNode;}p = p.children[index];}p.isEndingChar = true;}// 在 Trie 树中查找一个字符串public boolean find(char[] pattern) {TriaTree p = root;for (int i = 0; i < pattern.length; ++i) {int index = pattern[i] - 'a';if (p.children[index] == null) {return false; // 不存在 pattern}p = p.children[index];}return p.isEndingChar;}
}
复杂度分析
时间复杂度:
假设所有字符串长度之和为n
,构建字典树的时间复杂度为O(n)
假设要查找的字符串长度为k
,查找的时间复杂度为O(k)
空间复杂度:
字典树每个节点都需要用一个数组来存储子节点的指针,即便实际只有两三个子节点,但依然需要一个完整大小的数组。所以,字典树比较耗内存,空间复杂度较高。
如何优化?
可以牺牲一点查询的效率,将每个节点的子节点数组用其他数据结构代替,例如有序数组,红黑树,散列表等
例如,当子节点数组采用有序数组时,可以使用二分查找来查找下一个字符。缩点优化
将末尾一些只有一个子节点的节点,可以进行合并,但是增加了编码的难度。如图
字典树与散列表红黑树的比较
字典树的缺陷:
- 需要处理的字符串的字符集不能过大,否则存储空间过于浪费,即便是采用优化方案,也是在牺牲部分查询性能的基础上的
- 在字符串前缀重合较多的情况,才有比较好的性能表现
- 没有现成的字典树可以用,如果要使用需要手写,
- 字典树中使用到了指针,因此前后节点是不连续的,对 CPU 缓存不友好
综上:在字符串的精确查找场景中,推荐使用红黑树,散列表等数据结构。
而字典树,则适合在查找前缀的场景下,例如,搜索引擎一般在输入部分字符后,会显示一些预选关键字。这些关键字均是以输入的字符为前缀。
Trie 树构造原理、应用场景与复杂度分析相关推荐
- 哈夫曼树构造原理及方法
哈夫曼树(最优二叉树) 百度百科:https://baike.baidu.com/item/%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91/2305769?fr=aladdi ...
- 【NOIP模拟】彩色树【树形dp】【树链剖分性质】【复杂度分析】
题意:一棵初始时为空的树,依次加入 nnn 个叶结点,每次加入后询问 用若干不同颜色的路径将树边染色后 每个点到根经过的颜色数 的最大值 的最小值. n≤106n\leq 10^6n≤106 首先发现 ...
- 巧用 Trie 树,实现搜索引擎关键词提示功能
来源 | 码海 责编 | Carol 封图 | CSDN 付费下载于视觉中国 我们几乎每天都在用搜索引擎搜索信息,相信大家肯定有注意过这样一个细节:当输入某个字符的时候,搜索引框底下会出现多个推荐词, ...
- android搜索框功能实现_巧用 Trie 树,实现搜索引擎关键词提示功能
来源 | 码海责编 | Carol封图 | CSDN 付费下载于视觉中国我们几乎每天都在用搜索引擎搜索信息,相信大家肯定有注意过这样一个细节:当输入某个字符的时候,搜索引框底下会出现多个推荐词,如下, ...
- 数据结构与算法之美笔记——基础篇(下):图、字符串匹配算法(BF 算法和 RK 算法、BM 算法和 KMP 算法 、Trie 树和 AC 自动机)
图 如何存储微博.微信等社交网络中的好友关系?图.实际上,涉及图的算法有很多,也非常复杂,比如图的搜索.最短路径.最小生成树.二分图等等.我们今天聚焦在图存储这一方面,后面会分好几节来依次讲解图相关的 ...
- Trie树实现前缀自动补全 + AC自动机实现敏感词过滤
文章目录 背景 扩展 AC自动机 背景 最近参与了某业务系统的开发, 需要根据城市的名字简称,找到其官方的完整名称.比如云南的大理,其实其完整的名称是大理白族自治州.可以参考官方的行政区划,点这里. ...
- 字符串匹配数据结构 --Trie树 高效实现搜索词提示 / IDE自动补全
文章目录 1. 算法背景 2. Trie 树实现原理 2.1 Trie 树的构建 2.2 Trie树的查找 2.3 Trie树的遍历 2.4 Trie树的时间/空间复杂度 2.5 Trie 树 Vs ...
- 算法 | 动画+解析,轻松理解「Trie树」
Trie这个名字取自"retrieval",检索,因为Trie可以只用一个前缀便可以在一部字典中找到想要的单词. 虽然发音与「Tree」一致,但为了将这种 字典树 与 普通二叉树 ...
- 看动画轻松理解「Trie树」
作者 | 程序员小吴 责编 | 胡巍巍 扎心!"我学了半年 Python,还是找不到工作" https://edu.csdn.net/topic/python115?utm_sou ...
- Trie 树——Golang实现
Trie 树,也叫"字典树".顾名思义,它是一个树形结构.它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题. 现在,我们先来看下,Trie ...
最新文章
- (zt)Web 2.0奔路进行时
- 597个智慧城市相关试点将临大考
- Matlab与机器学习-- 数据的归一化
- hicoder - 1068 【RMQ or 线段树】
- idea 启动 springBoot debug很慢,正常启动很快是什么原因
- pycharm快捷键_春节快结束了回单位途中总结下pycharm快捷键
- 计算机网络-自顶向下方法(7th) 第五章 Problems 英文题目1-15+中文答案
- 代理模式(Proxy) 静态
- 一个简单SeekBar样式的例子
- Flink流式计算在节省资源方面的简单分析
- JavaScript上传图片方式
- v-for中的key
- 《我的青春谁做主》经典搞笑台词
- 【Python】10行代码获取海贼王最新目录
- 什么是搜索引擎???搜索引擎的介绍
- Bootstrap之折叠(Collapse)
- Android多功能视频播放器GSYVideoPlayer开发流程
- Python-玩转数据-利用百度高德经纬度地图定位
- 海上风电消防火灾报警系统中消防主机超远距离联网方案
- 无法启动此应用因为计算机丢失,开机无法启动此程序因为计算机中丢失怎么回事...
热门文章
- 企业不良资产的审计 不同类型区别对待
- Cadence OrCAD Capture在2K屏下原理图不能正常显示设置方法
- iPhone分辨率和坐标、设计图尺寸
- Android 集成Tinker踩坑记录
- LLM时代中的分布式AI
- 班委竞选题P45,T29.
- 软件设计 -- 模块独立性
- Magento安装错误Mage_Core_Model_Session_Abstract::getMessages()
- 【大模型AIGC系列课程 4-1】AI 代理介绍与应用
- 抛弃建立ext方式统一版本依赖,拥抱更方便的统一版本信息和依赖库版本号的新方式