关于树的最全知识就在这里了

前言

今天和大家来说说树,大家一下子就想到了原始森林、保护树木、滥砍滥发等关键字,不不不。。。我想说的是一种数据结构,废话不多说,上图你就知道了

正文

看了上面的图终于豁然开朗,就是这些东西搞的脑子昏昏涨涨的,动不动就要我手撕红黑树,反正我这种老年人是撕不出来了,但是原理还是需要说一说的。下面开始进入正文,什么???还没有进入正文,你TM在逗我。。。

数据结构按照逻辑来分类是集合、线性结构、树形结构、图形结构,但是为什么会有树形结构的产生呢,网上有一句经典的话可以解释,那就是为了弥补其他数据结构的不足,没毛病,真的没毛病哈。。。

那么传统的集合到底有什么问题呢,Java中都知道数组查询效率高,链表的插入删除效率高,那么有没有一种数据结构能完美的拥有较高的查询效率和插入删除效率呢,这个时候树就是一种比较好的选择了,树分为二叉树和多路查找树。

二叉树在使用中非常常见,就是最多有两个叶子节点的树,这里有一种特殊情况就是假如没有左子树或者右子树

怎么样,看着是不是跟链表一模一样,我们叫他左斜树或右斜树,如果二叉树中所有非叶子结点的度都是2,且叶子结点都在同一层次上,就是满二叉树,如果一个二叉树与满二叉树前m个节点的结构相同,这样的二叉树被称为完全二叉树。重点来了

二叉查找树(BST)

  • 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  • 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  • 任意节点的左、右子树也分别为二叉查找树;
  • 没有键值相等的节点。

说到这里我们开始说下这种树的插入,如上所述,就是正常的插入就行,是不是很惊喜

数据有了,然后前序遍历、中序遍历、后序遍历,最大值、最小值、前驱后继、删除、销毁了解一下,说到这里难道记忆中算法题中没有让你中序遍历排序后操作的么???这其中前驱后继稍微说下,找一个节点前驱的时候有三种情况,后继同理:

  • 如果节点存在左孩子,那前驱就是左孩子为根子树的最大节点
  • 没有左孩子,节点是一个右孩子,那前驱就是父节点
  • 没有左孩子,节点是一个左孩子,查找该节点的最低父节点并且父节点有右孩子,那前驱就这个最低父节点

但是二叉搜索树有一些很极端的情况会导致层级很多,查询效率低,为了解决这个问题平衡二叉树(AVL)出现了,他的不同点就是左右两个子树的高度差的绝对值不超过1,这样我们的查询效率就有了保证,但是带来了另外一个问题就是在插入的时候会破坏平衡二叉树的结构,这个时候就要通过旋转来解决这个问题,所以其实在插入的时候效率会变低的。需要旋转的情况分为四类:

  1. LL: LeftLeft,也称为"左左"。插入或删除一个节点后,根节点的左子树的左子树还有非空子节点,导致"根的左子树的高度"比"根的右子树的高度"大2,导致AVL树失去了平衡。
  2.  LR: LeftRight,也称为"左右"。插入或删除一个节点后,根节点的左子树的右子树还有非空子节点,导致"根的左子树的高度"比"根的右子树的高度"大2,导致AVL树失去了平衡。
  3.  RL: RightLeft,称为"右左"。插入或删除一个节点后,根节点的右子树的左子树还有非空子节点,导致"根的右子树的高度"比"根的左子树的高度"大2,导致AVL树失去了平衡。
  4.  RR: RightRight,称为"右右"。插入或删除一个节点后,根节点的右子树的右子树还有非空子节点,导致"根的右子树的高度"比"根的左子树的高度"大2,导致AVL树失去了平衡。

上面的四类,每个类型都有两种情况,会有左右两个节点的可能,所以总共是八中情况。其中LL、RR只需要旋转一次就能恢复平衡二叉树,LR、RL需要旋转两次。由于这种旋转严重的影响了插入的效率,所以红黑树诞生了

  • 每个节点颜色不是黑色,就是红色
  • 根节点是黑色的
  • 如果一个节点是红色,那么它的两个子节点就是黑色的(没有连续的红节点)
  • 对于每个节点,从该节点到其后代叶节点的简单路径上,均包含相同数目的黑色节点

相对于平衡二叉树,红黑树旋转情况少一点,虽然AVL树的时间复杂度虽然优于红黑树,但是对于现在的计算机,cpu太快,可以忽略性能差异,所以总体上红黑树整体性能略优于AVL树。如果想看红黑树的具体插入过程可以看下HashMap源码解析(JDK1.8)

这也是为什么JDK1.8之后hashMap改成数组+链表+红黑树的原因。对于哈夫曼树,又称最优二叉树, 是一种带权路径长度最短的二叉树。大家有兴趣自行研究下。

说完了二叉树,接下来说下多路复用树,B树,是一种自平衡的树,其实也是一个二叉树,但是这种数据结构能够让查找数据、顺序访问、插入数据及删除的动作,都在对数时间内完成。适用于读写相对大的数据块的存储系统,例如磁盘。还有B+树,大家一听肯定不会陌生,Mysql中主键索引,也是面试常问的。动不动就要问你为啥主键索引要用B+树,真是一脸懵逼,想说一句,TM以前就是这样用的,我怎么知道。。。

不慌,看这里,在B树基础上,为叶子结点增加链表指针(B树+叶子有序链表),所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中。b+树的非叶子节点不保存数据,只保存子树的临界值(最大或者最小),所以同样大小的节点,b+树相对于b树能够有更多的分支,使得这棵树更加矮胖,查询时做的IO操作次数也更少,所以查询效率更高,是不是很完美。B+ 树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。适用于关系型数据库(如Mysql)和操作系统的文件系统中。

R树是用来做空间数据存储的树状数据结构。例如给地理位置,矩形和多边形这类多维数据建立索引。大家有兴趣自己看下吧。

后记

终于又是洋洋洒洒好多字,然后在不知不觉中就结束了,终于个人的公众号也开通了,大家有兴趣可以关注一波!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值