Trie 树构造原理

字典树,又称 Trie 树,是一种专门用于字符串匹配的树形结构,能够高效的在一组字符串中寻找所求字符串,与红黑树,散列表类似,但是又有其优势。

如何构造一颗 Trie 树
假设我们有一组字符串:abcadfadrfsiab
Trie 树的本质,就是利用字符串之间的公共前缀,将重复的前缀合并在一起。如图:

根节点不包含任何信息,从根节点一路往下到灰色节点,便是一个字符串。

注意:灰色节点并不一定是叶子节点,当字符串组中存在abcabcdfg这样的时,前者是后者的前缀,为了区分是两个字符串,需要给每个字符串的结尾字符做标记。

在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)

空间复杂度:
字典树每个节点都需要用一个数组来存储子节点的指针,即便实际只有两三个子节点,但依然需要一个完整大小的数组。所以,字典树比较耗内存,空间复杂度较高。

如何优化?

  1. 可以牺牲一点查询的效率,将每个节点的子节点数组用其他数据结构代替,例如有序数组,红黑树,散列表等
    例如,当子节点数组采用有序数组时,可以使用二分查找来查找下一个字符。

  2. 缩点优化
    将末尾一些只有一个子节点的节点,可以进行合并,但是增加了编码的难度。如图

字典树与散列表红黑树的比较

字典树的缺陷:

  1. 需要处理的字符串的字符集不能过大,否则存储空间过于浪费,即便是采用优化方案,也是在牺牲部分查询性能的基础上的
  2. 在字符串前缀重合较多的情况,才有比较好的性能表现
  3. 没有现成的字典树可以用,如果要使用需要手写,
  4. 字典树中使用到了指针,因此前后节点是不连续的,对 CPU 缓存不友好

综上:在字符串的精确查找场景中,推荐使用红黑树,散列表等数据结构。

而字典树,则适合在查找前缀的场景下,例如,搜索引擎一般在输入部分字符后,会显示一些预选关键字。这些关键字均是以输入的字符为前缀。

Trie 树构造原理、应用场景与复杂度分析相关推荐

  1. 哈夫曼树构造原理及方法

    哈夫曼树(最优二叉树) 百度百科:https://baike.baidu.com/item/%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91/2305769?fr=aladdi ...

  2. 【NOIP模拟】彩色树【树形dp】【树链剖分性质】【复杂度分析】

    题意:一棵初始时为空的树,依次加入 nnn 个叶结点,每次加入后询问 用若干不同颜色的路径将树边染色后 每个点到根经过的颜色数 的最大值 的最小值. n≤106n\leq 10^6n≤106 首先发现 ...

  3. 巧用 Trie 树,实现搜索引擎关键词提示功能

    来源 | 码海 责编 | Carol 封图 | CSDN 付费下载于视觉中国 我们几乎每天都在用搜索引擎搜索信息,相信大家肯定有注意过这样一个细节:当输入某个字符的时候,搜索引框底下会出现多个推荐词, ...

  4. android搜索框功能实现_巧用 Trie 树,实现搜索引擎关键词提示功能

    来源 | 码海责编 | Carol封图 | CSDN 付费下载于视觉中国我们几乎每天都在用搜索引擎搜索信息,相信大家肯定有注意过这样一个细节:当输入某个字符的时候,搜索引框底下会出现多个推荐词,如下, ...

  5. 数据结构与算法之美笔记——基础篇(下):图、字符串匹配算法(BF 算法和 RK 算法、BM 算法和 KMP 算法 、Trie 树和 AC 自动机)

    图 如何存储微博.微信等社交网络中的好友关系?图.实际上,涉及图的算法有很多,也非常复杂,比如图的搜索.最短路径.最小生成树.二分图等等.我们今天聚焦在图存储这一方面,后面会分好几节来依次讲解图相关的 ...

  6. Trie树实现前缀自动补全 + AC自动机实现敏感词过滤

    文章目录 背景 扩展 AC自动机 背景 最近参与了某业务系统的开发, 需要根据城市的名字简称,找到其官方的完整名称.比如云南的大理,其实其完整的名称是大理白族自治州.可以参考官方的行政区划,点这里. ...

  7. 字符串匹配数据结构 --Trie树 高效实现搜索词提示 / IDE自动补全

    文章目录 1. 算法背景 2. Trie 树实现原理 2.1 Trie 树的构建 2.2 Trie树的查找 2.3 Trie树的遍历 2.4 Trie树的时间/空间复杂度 2.5 Trie 树 Vs ...

  8. 算法 | 动画+解析,轻松理解「Trie树」

    Trie这个名字取自"retrieval",检索,因为Trie可以只用一个前缀便可以在一部字典中找到想要的单词. 虽然发音与「Tree」一致,但为了将这种 字典树 与 普通二叉树 ...

  9. 看动画轻松理解「Trie树」

    作者 | 程序员小吴 责编 | 胡巍巍 扎心!"我学了半年 Python,还是找不到工作" https://edu.csdn.net/topic/python115?utm_sou ...

  10. Trie 树——Golang实现

    Trie 树,也叫"字典树".顾名思义,它是一个树形结构.它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题. 现在,我们先来看下,Trie ...

最新文章

  1. (zt)Web 2.0奔路进行时
  2. 597个智慧城市相关试点将临大考
  3. Matlab与机器学习-- 数据的归一化
  4. hicoder - 1068 【RMQ or 线段树】
  5. idea 启动 springBoot debug很慢,正常启动很快是什么原因
  6. pycharm快捷键_春节快结束了回单位途中总结下pycharm快捷键
  7. 计算机网络-自顶向下方法(7th) 第五章 Problems 英文题目1-15+中文答案
  8. 代理模式(Proxy) 静态
  9. 一个简单SeekBar样式的例子
  10. Flink流式计算在节省资源方面的简单分析
  11. JavaScript上传图片方式
  12. v-for中的key
  13. 《我的青春谁做主》经典搞笑台词
  14. 【Python】10行代码获取海贼王最新目录
  15. 什么是搜索引擎???搜索引擎的介绍
  16. Bootstrap之折叠(Collapse)
  17. Android多功能视频播放器GSYVideoPlayer开发流程
  18. Python-玩转数据-利用百度高德经纬度地图定位
  19. 海上风电消防火灾报警系统中消防主机超远距离联网方案
  20. 无法启动此应用因为计算机丢失,开机无法启动此程序因为计算机中丢失怎么回事...

热门文章

  1. 企业不良资产的审计 不同类型区别对待
  2. Cadence OrCAD Capture在2K屏下原理图不能正常显示设置方法
  3. iPhone分辨率和坐标、设计图尺寸
  4. Android 集成Tinker踩坑记录
  5. LLM时代中的分布式AI
  6. 班委竞选题P45,T29.
  7. 软件设计 -- 模块独立性
  8. Magento安装错误Mage_Core_Model_Session_Abstract::getMessages()
  9. 【大模型AIGC系列课程 4-1】AI 代理介绍与应用
  10. 抛弃建立ext方式统一版本依赖,拥抱更方便的统一版本信息和依赖库版本号的新方式