红黑树在HashMap中的应用(一)

红黑树在HashMap中的应用(一)

​ 现在来填上一篇博客的坑,讲一讲红黑树在HashMap中的应用。

​ 在讲之前,先要了解一下红黑树,再去阅读源码。本文就是这样的一个结构。但是一开始没有想到红黑树很复杂,篇幅比预期的要大,所以本次红黑树的记录分为三期,坑一定要慢慢填。。

了解红黑树

​ 分析源码肯定要先了解相关概念,了解了概念去看源码就豁然开朗,要不然一直都像无头苍蝇一样,抓不到头绪。

红黑树的历史

​ 红黑树最开始由鲁道夫·贝尔在1972年发明,被称为"对称二叉B树",它现代的名字源于Leo J. Guibas和Robert Sedgewick于1978年写的一篇论文。但是其代码的实现非常不容易,所以在2008年Robert Sedgewick编写了一个幻灯片,介绍了左倾红黑树,并且给出了简单的实现代码,就此,红黑树就逐渐变成我们如今了解的样子。

​ 作为一个合格的开发人员,应该去了解概念的最初形成,知道其根源的理论。网上的大部分文章都介绍了红黑树的五个性质,但是性质来源和为什么有这些性质并没有说清楚。这里因为本人能力有限(英语方面),使用谷歌翻译但是翻译的一塌糊涂。所以最后虽然找到了论文和PPT,但是看不懂。。。(英语的重要性)下面放上链接,同时也希望自己后续英语能力上来后能够填上这个坑。

A dichromatic framework for balanced trees

Left-Leaning Red-Black Tree

红黑树的来源和变种

​ 如果你也和我一样在网上找了一圈相关的论文资料,估计这个小节你已经有了相关的概念。红黑树并不是凭空出来的新概念,只是将最开始的概念进行完善和代码化。下面我就按照完善的顺序介绍各种二叉树的变种。直到最后介绍红黑树,

二叉树

​ 二叉树(binary tree)是最开始的树,就是一个简单的只有两个字节点的树。甚至节点之间都没有顺序。

image-20210309184758580

二叉查找树

​ 二叉查找树(BST,binary search tree)是二叉树的进化,在二叉树的基础上增加了有序性,我们平时说的二叉树也是指的二叉查找树。二叉查找树能够快速的查找、删除、插入元素。

image-20210309185136325

​ 但是二叉查找树有一个致命因素,如果元素在特殊情况下插入,二叉树会变成一种单链表,如下图:

image-20210309185326382

​ 所以二叉查找树在特殊情况下的时间复杂度非常差。

AVL树

​ AVL树(由发明者Adelson-Velsky 和 Landis 的首字母缩写命名)是指任意节点的两个子树的高度差不超过1的平衡树。

image-20210309190241163

​ 上面的树就是AVL树,不是很容易理解,并且AVL树实现自平衡的过程很复杂,这里就不再详细描述了。

2-3树

​ 2-3树的定义如下:每个具有子节点的节点(内部节点,internal node)要么有两个子节点和一个数据元素,要么有三个子节点和两个数据元素的自平衡的树,它的所有叶子节点都具有相同的高度。

image-20210310163055451

​ 2-3树的逻辑还是能够理解的,主要就是维持2-3树的特点,如果出现了不符合2-3树的特征,就需要将数据元素或者字节点往上移动。下面列举一个2-3树生长轨迹图。

image-20210310165516582

​ 图的来源为:算法网

2-3-4树

​ 2-3-4树,它的每个非叶子节点,要么是2节点,要么是3节点,要么是4节点,且可以自平衡,所以称作2-3-4树。2节点:包含两个子节点和一个数据元素;3节点:包含三个子节点和两个数据元素;4节点:包含四个子节点和三个数据元素;

image-20210310165929418

​ 2-3-4树是2-3树的进阶版,在2-3树的转换过程中会发现有一种中间状态和上面的图类似,就是具有四个节点和三个数据元素,如果这种状态合法,它就是2-3-4树。

​ 如果2-3-4树转换的中间状态也是合法的,就又产生了一种新的树,2-3-4-5树。这样类似的树统称为B树,它允许一个节点可以有多于两个子节点,同时,也是自平衡的,叶子节点的高度都是相同的。B树多了一个概念叫“度”,2-3树的度就是3,2-3-4树多度就是4,度就是表示该树最多拥有多少字节点。

红黑树

​ 红黑树其实是由2-3-4树变种而来(也有说是2-3树变种而来,这里不再讨论详细内容),因为2-3-4树代码的实现比较复杂,所以产生了红黑树(代码实现也不简单)。先说一下红黑树的五条性质。

  • 节点是要么红色或要么是黑色。
  • 根一定是黑色节点。
  • 每个叶子结点都带有两个空的黑色结点(称之为NIL节点,它又被称为黑哨兵)。
  • 每个红色节点的两个子节点都是黑色(或者说从每个叶子到根的所有路径上不能有两个连续的红色节点)。
  • 从任一节点到它所能到达得叶子节点的所有简单路径都包含相同数目的黑色节点。

​ 现在五条性质不清楚原因没有关系,可以在后面慢慢的去了解其意义,或者在上面的论文和幻灯片中寻找答案。和我之前想的一样,不同的高度看到和理解的东西是不一样的,很难一次就理解红黑树的全部概念。列举一个和上面2-3-4树数据元素一致的红黑树。

image-20210310182116361

​ 这样看的话是不是就能理解为什么红黑树是2-3-4树的变种了?对比五条性质就更能理解这个图。如果上面的两个图片还是抽象,我寻找了画的比我好的一个示意图。

image-20210310194048137

​ 到此,红黑树的来源和中间的一些变种就全部了解完毕。这一部分借鉴了其他人的博客,这里放上链接。

红黑树的来源和变种的讲解

红黑树的五条性质及其解释

​ 红黑树的五条性质在上面有说到过,下面就一一分析这五条性质。

2-3-4树和红黑树之间的转换

​ 既然说了红黑树来源于2-3-4树,所以两者肯定可以转换,并且红黑树的五条性质也是依赖于这些转换过程的。下面给出转换的图例和解析。2-3-4树只存在2、3、4节点的情况,临时的节点情况不再本次分析之内。

  • 2节点。2节点比较简单,直接转换为红黑树中的黑色节点即可,如下图:

image-20210314142331015

​ 这个还是很好理解的,就是简单将节点赋予颜色,没有什么难点。

  • 3节点。3节点有些特殊,存在两个情况,也是红黑树的分支由来,即左倾红黑树和右倾红黑树。如下图:

image-20210314143232558

​ 这里就可以看到颜色的意义,红色本身是没有任何含义的,红色的节点是要结合它的父树一起来看才能看出这棵红黑树树的含义。

  • 4节点。4节点和2节点相似,只存在一种情况,如下图:

image-20210314143711140

​ 到此,就可以将任意的一个2-3-4树转换为红黑树,并且可以确定红黑树的颜色。但是因为3节点的存在,所以一个2-3-4树能转换为不同的红黑树,一个红黑树不能转换为多个2-3-4树。

红黑树的性质解析

​ 红黑树的性质上面已经说过了,并且也已经了解了2-3-4树和红黑树的互相转换,可以开始解析对应的五条性质了。

  • **节点是要么红色或要么是黑色。**这个性质还是比较好理解的,红黑树只存在黑色和红色,如果有其他颜色也就不叫红黑树了。需要注意的是如果一个红黑树全部存在黑色或者红色呢?也不是不可以,但是红黑树是来源于2-3-4树,全是黑色或者全是红色显然无法分辨出是2节点还是3节点,一个红黑树也就对应多个2-3-4树了。不符合要求,并且代码也无法实现。

  • **根一定是黑色节点。**这个性质可能要思考一下,红黑树来源于2-3-4树,通过上面的转换不难发现无论是2、3还是4节点,最后转换为红黑树都是黑色节点在上。所以根节点就无论如何都是黑色的了。

  • **每个叶子结点都带有两个空的黑色结点(称之为NIL节点,它又被称为黑哨兵)。**这个性质我现在还不是很理解,找了一下,大部分的解释是为了区分某些不属于红黑树的特殊情况,这里也留个坑吧,也欢迎大佬给出解答。

  • **每个红色节点的两个子节点都是黑色(或者说从每个叶子到根的所有路径上不能有两个连续的红色节点)。**这个性质也需要思考一会,还是那句话,红黑树来源于2-3-4树,看看2-3-4树什么情况下会转换为红色树,只有3和4节点,之前也说过红树是结合父树来看的,如果3节点增加红树,对应的就是4节点,但是4节点只存在唯一的情况,所以不行。4节点就更容易理解了,添加一个红树,变为5节点,但是5节点是临时态,实际是不应该存在的,最后还是会转换为其他形态。解释如下图。

    image-20210314150143548

    image-20210314150159674

  • **从任一节点到它所能到达得叶子节点的所有简单路径都包含相同数目的黑色节点。**这个性质也是能够理解的,通过上面的转换可以看到只有黑色节点代表一层,红色节点其实和父黑色节点同属于一层,所以黑色节点代表层数。同时红黑树是做了平衡的,和2-3-4树一样,到达子节点的层数都是一致的,即到达任何一个子节点的黑色节点树相同。

红黑树的操作及其分析

​ 讲解完了红黑树的来源和性质,下面就可以讲解一下红黑树具体的操作和对这些操作的分析。

​ 红黑树的平衡操作有三种:左旋转、右旋转、染色。下面就一一解析这些操作。具体的插入和操作放到下一片博客讲。

左旋转

​ 左旋转的作用就是将一个向右倾斜的二叉树平衡,转化为左链接。如下示意图。(插入顺序为1-2-3)

image-20210310195710789

​ 通过将这个二叉树左旋,就是将1节点变为2节点的左节点,同时改变颜色(这一步骤其实不涉及染色)。变成如下图。

image-20210310200014187

右旋转

​ 举一反三,看过上面就大致猜到了右旋转就是将左倾斜的二叉树平衡,转化为右链接。如下示意图。(插入顺序为3-2-1)

image-20210310200442968

​ 和上面的相反,将二叉树右旋,将3节点变为2节点的右节点。变成如下图。

image-20210310200635557

染色

​ 旋转完后或者插入节点后,很大概率红黑树的节点颜色是不符合要求的,所以需要将红黑树节点的颜色进行改变,变成符合五条性质的红黑树。还是以上面的左旋转为例。

​ 旋转完毕,但是不染色。

image-20210310201209652

​ 很明显不符合红黑树的性质4,所以要对节点的颜色进行变换,变成符合要求的如下的红黑树。

image-20210310200635557

​ 红黑树为了平衡的三个操作都已经了解了,剩下的就是实践了,这一部分比较耗费时间和画图。。。所以不再博客中叙述。只需要记住一点,无论经过什么操作,红黑树需要满足自身的平衡要求并且也要符合红黑树的五条性质,剩下的自己就是慢慢画和理解了。

​ 这一部分也借鉴了其他人的成果,这里放上链接。

红黑树的操作解析

红黑树的在线演示图,可以在这里验证自己的思路

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值