提到数据结构中的树(Tree) ,大家应该都不陌生,相关书籍中都有大段篇幅的介绍,刷 Leetcode 的时候会遇到很多相关问题。很多人往往会用 “手写红黑树” 来形容面试难度很高。

那么,除了红黑树之外,还有哪些常见的树结构?它们被用在什么领域?又解决了什么问题?接下来,我们就用几篇文章,来给大家做一个简单的介绍。

大家好,我是不会写代码的纯序员——Chunel Feng。各位绅士们,很高兴我们又在这里见面了。

刷 leetcode 的童鞋,肯定写过二叉树的遍历、递归、查询等逻辑,笔试的时候 6 的飞起,人均 sp。但很多童鞋可能也会有这样一种感觉:这些东西只能应付面试,不实用,工作了好好几年了,根本没用过。

其实,我们在工作中接触到的很多东西,底层的本质就是一棵树型结构,只是有前人为我们造好了屏蔽实现细节的轮子,才让我们的工作变得如此丝滑。举两个常见的例子:C++里的 std::set 和 std::map 结构,底层就是一颗树;常见的数据库存储引擎,底层也是树型结构。

那么,常用的数据结构里还有哪些常见树呢?它们又会被应用在哪里?用于解决什么样的问题? 下面,我们就从以上几个问题入手,来介绍一下我所知道的一些 Tree 方面的知识,希望对大家有所帮助。

在开始之前,首先说明,本文偏科普和综述,并不会对每种树做非常详细的介绍,也不会上什么类似红黑树旋转的代码。主要目的是让大家知道有这些内容,如果今后有需要用到的地方,自己查缺补漏即可。本人水平有限,如果有描述的错误或遗漏,也欢迎大家随时补充和交流。

下面我们正式开始:

二叉树

BST 搜索二叉树 Binary Search Tree

树,最常见的用法,就是用于数值查找。通过在建树的时候,将大于 root 的值放到右边、小于 root 的值放到左边,即可在查询的时候,减少比较次数,实现加速查询。

但是,随着数据的插入越来越多,树的结构会造成扭曲(不平衡)。比如,往 bst 中插入一个递增数组的时候,普通的 BST 会退化成一个链表,从而严重影响查询性能。

AVL 平衡二叉树 Height-Balanced Binary Search Tree

于是,AVL 平衡二叉树诞生了。AVL 的名字,取自于作者 Adelson-Velskii 和 Landis 的首字母缩写(纯序员暗自感慨,如果是第一位作者独立发明的话,那数据结构课上就又多了个话题)。

AVL 树通过在插入过程中的旋转逻辑,使得树的自身高度差严格控制在 1 之内,从而解决了退化成 list 的问题。但是,频繁的旋转增加了树构建的成本。

RBT 红黑树 Red Black Tree

为了降低树构建时的成本,红黑树诞生了。红黑树通过将节点设定成 Red or Black,和同一条边中 Black 节点的数量相同等约束条件,在保证了树基本平衡的情况下,优化了自旋转流程。

红黑树可以有效的平衡建树时的旋转次数和查找时的退化问题,并且也在实际编程中得到了广泛的应用。比如 C++中的 std::map 和 Java 里的 TreeMap 的底层就是一颗红黑树,nginx 和 epoll 源码中也有所使用。

字典树

Trie 前缀树

Trie 树是常见的字典树,通常被用于字符串查询和排序。它的形式,是在根节点的所有路径中,有序的依次存入一个对应字符。这样做,一方面可以降低海量字符串存储所占用的空间,另一方面也使得字符串得以有序的排列,同时也可以记录重复出现次数。

这算是搜索引擎里最最最简单的样例吧,记住哦,面试中经常问的。想继续往搜索引擎方面了解一些的童鞋,可以看一下 FST(Finite State Transducers,有限状态转移机),这个就不属于【树】的范畴了,我们不在这里讨论了。

Radix 压缩前缀树,也叫基数树

样子跟前面提到的 Trie 树有点相似。相比于 Trie 中一个一个往下追加的流程,Radix 在插入的时候通过分裂机制使得仅包含一条链路的字符【压缩】到一起。从而在保持原有查询、排序功能的前提下,进一步降低了数据的存储占用量。顺便说一句,Radix 树中的节点,还适合用于存放类似 .*? 这种正则匹配相关的信息。

一图胜千言,看到上面这个图,我想大家应该都懂了。Radix 树有一个常见的应用,就是文件路径查找或匹配,这一点做前后端交互的朋友应该有所涉及。

/usr/local/include/         (14KB)
/usr/local/bin/             (25KB)
/usr/study/book/            (3MB)
/usr/study/.video/          (380GB)
...

比如,我电脑中的文件夹分类吧,用 Radix 树存储的话,就比 Trie 节省了很多空间,因为 /usr,/local,/study这几个信息,明显是可以合并到一个节点中的。

Suffix tree 后缀树

上面聊到的两种字典树,都属于前缀树,其实还有后缀树。后缀树是对一个长字符串的详尽描述(注意,是一个 string 对应一棵后缀树,不是海量 string 放到一棵树上)。树的每条路径记录了一个后缀信息,后缀下标用于记录从第 x 个字符开始计算,从而简化的查询流程。主要用途有:字符串匹配,查找最长公共子串,查找最长重复子串等

这个讲起来有点复杂,有兴趣的朋友可以去 B 站搜索:轻松掌握 suffix tree[1] ,讲的非常通俗易懂,墙裂推荐。

本章小节

本章是这个系列的第一篇内容,主要是聊了我写这个系列的文章的出发点和目的,也简单介绍了几种类型的树,并梳理了他们的使用场景和异同,希望对大家有所帮助。

在这个系列接下来的几篇文章中,我们还会继续给大家介绍一些常见的树结构,比如lsm 树,kd 树、哈夫曼树等等。也希望对类似话题感兴趣的朋友,可以加我微信,一起讨论和交流相关的内容。

引用链接

[1] 轻松掌握 suffix tree: https://www.bilibili.com/video/BV1c741137GD?spm_id_from=333.999.0.0


长按识别下图二维码,关注公众号「Doocs 开源社区」,第一时间跟你们分享好玩、实用的技术文章与业内最新资讯。

心中有“树”!图文并茂介绍数据结构中常见的树(一)相关推荐

  1. 心中有“树”!图文并茂介绍数据结构中常见的树(二)

    计算机科学家尼古拉斯·沃斯(Niklaus Wirth)曾说过:编程=数据结构+算法 ,可见数据结构在编程中的重要性. 50 年过去了,计算机行业日新月异,大佬的这句名言是否还适用于当下?使用成熟且丰 ...

  2. 心中有“树”!图文并茂介绍数据结构中常见的树(三)

    在前面两篇文章中,我们简要介绍了数据结构中的各种[树]在搜索.数据库等领域的使用场景,希望对大家有所帮助. 本篇内容,是我们 <心中有"树"> 系列的最后一篇,我会在这 ...

  3. 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

    原文:http://blog.csdn.net/sup_heaven/article/details/39313731 数据结构中常见的树(BST二叉搜索树.AVL平衡二叉树.RBT红黑树.B-树.B ...

  4. 数据结构中常见的各种树原理详解(学习笔记)

    文章目录 01.回顾 1.树 02.二叉树 3.堆 堆排序 优先队列 索引优先队列 3.二叉搜索树(二叉查找树) 4.二叉平衡树(ALV) 02. 2-3查找树 2-3树的性质 03.红黑树 红黑树插 ...

  5. 数据结构中常见的时间复杂度分析题目

    数据结构中常见的时间复杂度分析题目 时间复杂度基本概念 例如上面的代码,我们可以表示成T(n) = O(f(n)),而f(n) = 2n + 3.我们使用大O表示法可以写为T(n) = O(n). 分 ...

  6. 图解:数据结构中的6种「树」,柠檬问你心中有数吗?

    数据结构这门课程是计算机相关专业的基础课,数据结构指的是数据在计算机中的存储.组织方式. 我们在学习数据结构时候,会遇到各种各样的基础数据结构,比如堆栈.队列.数组.链表.树...这些基本的数据结构类 ...

  7. 图解:数据结构中的6种「树」,你心中有数吗?

    数据结构这门课程是计算机相关专业的基础课,数据结构指的是数据在计算机中的存储.组织方式. 我们在学习数据结构时候,会遇到各种各样的基础数据结构,比如堆栈.队列.数组.链表.树...这些基本的数据结构类 ...

  8. [数据结构]数据结构中各种树

    阅读目录 1. 二叉树 2. 二叉查找树 3. 平衡二叉树 3.1 平衡查找树之AVL树 3.2 平衡二叉树之红黑树 4. B树 5. B+树 6. B*树 7. Trie树 数据结构中有很多树的结构 ...

  9. [Data Structure] 数据结构中各种树

    数据结构中有很多树的结构,其中包括二叉树.二叉搜索树.2-3树.红黑树等等.本文中对数据结构中常见的几种树的概念和用途进行了汇总,不求严格精准,但求简单易懂. 文章目录 1. 二叉树 2. 二叉查找树 ...

最新文章

  1. linux 重定向类型 超级块 i节点
  2. JS window对象 Navigator对象 Navigator 对象包含有关浏览器的信息,通常用于检测浏览器与操作系统的版本。...
  3. 前端微信签名验证工具_微信jssdk 签名错误排查方法
  4. qt接收服务器信息中文乱码,在qt提取lineedit中的中文字符串,通过tcp通信时,服务器接收乱码的情况,解决办法...
  5. spring-boot注解详解(五)
  6. 实验一 DOS命令解释程序的编写
  7. ThreadLocal 从源码角度简单分析
  8. citrix xendesktop edition
  9. python中kmeans怎么导入数据集_通过Python实践K-means算法
  10. asp.net 实现登陆实例
  11. 浅谈协方差矩阵 再谈协方差矩阵之主成分分析
  12. 2018年最新税收分类编码_这是我们在2018年推出的所有免费编码课程
  13. [可靠消息]2020美赛结果公布时间
  14. 计算机等级考试一级宝典,计算机等级考试一级通关宝典.doc
  15. win7电脑蓝屏没有修复计算机,技术编辑教您win7电脑蓝屏怎么办
  16. word文档中表格计算机功能在哪,word文档筛选功能在哪里
  17. PRML读书会第五章 Neural Networks(神经网络、BP误差后向传播链式求导法则、正则化、卷积网络)...
  18. VS Code 常用必备插件
  19. 创建一个子进程,子进程向无名管道中写入数据,父进程打印输出。
  20. XZ_iOS之优秀网站推荐

热门文章

  1. 人工智能创业的“风口”和“泡沫”
  2. 我有故事,你有酒吗?(一)
  3. Load_balance函数情景分析
  4. odbc数据 mysql数据库_odbc连接数据库
  5. 【解决】在 IPMONTR.DLL 中初始化函数 INITHELPERDLL 启动失败,错误代码为 10107
  6. 控制JSP页面上的文本框只能输入数字
  7. 在VS2017上配置Opencv342(完整配置过程)
  8. linux给磁盘分区与格式化
  9. 神经网络模型matlab例子,神经网络及其matlab实现
  10. AtCoder 2068 すぬけ君の塗り絵 / Snuke's Coloring