红黑树

红黑树

也是前两天查面试题的时候查到的,B/B+树和红黑树基本上是面试Java工程师的必问问题,前者是用于数据库索引,后者是用在Java的集合类的底层实现,在JDK的TreeMap和TreeSet类底层就是使用红黑树,Java8之后的HashMap在数据量大的时候也会转换成红黑树,所以这篇就讲一下红黑树吧(什么叫“面试造火箭,工作拧螺丝”,面试官就喜欢问这些底层的东西,虽然用不上,还是得弄懂)

本文内容
  1. 红黑树
红黑树

先说一下,二叉查找树有什么缺点,才让红黑树得以生存,先放个二叉查找树
在这里插入图片描述
这是最最最简单的二叉查找树,看起来没有问题,我们来插入数据,依次插入18,17,16,15 ,就变成了这样
在这里插入图片描述
这依然还是一个二叉查找树,但是已经趋于线性,而这种情况的查询效率大打折扣,换个词来说,这棵树不平衡,所以红黑树就是解决这个问题

先来说红黑树的特征,红黑树是一种自平衡的二叉查找树,所以他符合二叉查找树的基本特征,在此之上,还有如下特征:

  1. 所有节点都是红色或黑色。
  2. 根节点是黑色。
  3. 每个叶子节点都是黑色的空节点(NIL节点)。
  4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
  5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

放一个红黑树出来,依次解释
在这里插入图片描述
从百度上找的一个图,难得画了,对比着来解释上面的概念,第一,所有节点都是红色或者黑色,第二,根结点是黑色,第三,叶子节点都是黑色的空节点NIL,第四,每个红色节点的子节点是黑色,且不能有两个连续的红色节点,这四点从图上都可以看出来,第五,从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点,这里注意,说的是叶子节点,NIL的,不是NIL的父节点,所以这里数一下也很明显可以看出来,所以这个概念结合图来说的话,就很容易懂了

这么多限制条件,使得红黑树和二叉查找树相比,能够保证红黑树的自平衡,使得从根节点到叶子节点的最长路径不超过最短路径的两倍,从而不会出现接近线性的情况

所以可以看出,红黑树和二叉查找树的查找效率差不多,就是在插入和删除的时候红黑树不会出现线性,而是会实现自平衡,在说插入和删除操作之前,得先讲几个概念:“左旋”,“右旋”,“变色”

左旋

逆时针旋转树的两个节点,使得父节点被自己的右孩子取代,而自己成为自己右孩子的左孩子。不容易理解,上图:
在这里插入图片描述
在这个图中,父节点x被y取代,然后x成了y的左孩子,这就是左旋

右旋

对应左旋的概念就很简单了,顺时针旋转树的两个节点,使得父节点被自己的左孩子取代,而自己成为自己左孩子的右孩子,上图
在这里插入图片描述
父节点x被y取代,然后x成了y的右孩子

变色

很简单,就是在红黑树,节点的颜色转换,红色变黑色,黑色变红色

说这三个有什么用,这就是红黑树实现自平衡的基本操作,红黑树的插入操作有很多种情况,我就挑一种情况进行解释:

原始树:
在这里插入图片描述
在这个图的基础上插入元素21,如下:
在这里插入图片描述
按照正常二叉树的规矩,我们要把21放在22的左孩子,但是此时的树已经不是红黑树,所以需要进行调整,首先进行变色,将节点22变色,对应的父节点25变红色,22与27均变为黑色,如图:
在这里插入图片描述
此时的25变成了红色节点,如果继续将17进行变色,则破坏了红黑树的规则,所以不能直接将17变为黑色,需要进行左旋继续变换,将13看做X,17看做Y,如图:
在这里插入图片描述
在这里插入图片描述
此时根据规则进行变色,17成为根结点,变为黑色,根据规则五,将13变成红色,同时8变成黑色,1和11变成红色,如图:
在这里插入图片描述
此时检查一遍规则,发现在17–13–8--1–6--NIL这条路上有4个黑色节点,其他路径都是3个黑色节点,不符合规则五,所以继续进行变换,此时将13看做X,8看做Y进行右旋变换,如图:
在这里插入图片描述
在这里插入图片描述
此时根据规则,先将8变为红色,对应的1和13变为黑色,6和15变成红色,如图:
在这里插入图片描述
此时再看,已经符合了红黑树的标准,所以调整结束,这个插入操作完成

整个过程看起来比较麻烦,实际上遵循了以下几个规则,首先介绍一下几个名词,新插入节点(就比如我们插入的22),父节点(就是新插入的结点的父节点,例子中的22),祖父节点(就是新插入节点的父节点的父节点,例子中的25),叔节点(就是新插入的结点的祖父节点的另一个孩子,例子中的27),然后整个变换的规则如下:

  1. 插入红色结点(一般新插入的结点默认为红色,根结点始终为黑色,插入黑色也可以,但是会增加路径上的黑色结点,很容易破坏红黑树的第五条规则,调整很麻烦,所以选择红色)

  2. 如果父结点为黑色,红黑树性质继续保持,直接插入,操作结束

  3. 如果父结点为红色,则破坏了红黑树的第四条规则,需要进行调整

    3.1 如果叔节点为黑色,则进行旋转操作:如果黑色节点多的路径在左边,则进行右旋操作;如果黑色节点多的路径在右边,则进行左旋操作

    3.2 如果叔结点为红色,则将父结点和叔结点一起变为黑色,祖父结点变为红色,此时有可能祖父结点的父结点也可能为红色,依旧会破坏红黑树的性质,此时需要将祖父结点作为新插入的结点继续向上迭代进行平衡操作,在迭代时如果调整到根,根依旧要保持为黑色结点

变换规则如果看不懂的话就结合上面的例子,应该很容易理解了

红黑树的删除操作比插入要更复杂一点,所以这里就不多讲了,给个链接自己看一下吧

https://zhuanlan.zhihu.com/p/22800206

网上也有很多写红黑树的博客,可以自己找点看看,很容易找的,因为这个确实是个比较有意思的数据结构

举例中的图片来源如下,侵权请联系,谢谢

http://www.sohu.com/a/201923614_466939

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值