数据结构与算法:三步学会红黑树--图文详解

 推荐看书:java数据结构和算法

考虑到有些童鞋看”java数据结构与算法”时,难以理解红黑树这一节,我对这一节的核心"插入一个新节点"章节,进行大白话的解释和思路流程的再梳理。

为了使得插入节点后的树是红黑二叉树,要怎么变色旋转插入?可以归纳为三种情况,并且这三种情况要按序执行

1 在下行途中的颜色变换: 

         即遇到两个子节点为红色的父节点时,执行变色,如图1-1中 13 18 和19。

         执行时间点:插入节点前执行

下图插入节点9(即0009)时的规则流程:


---------------------图1-1---------------------------       

        解释:如图1-1中,其中50为根节点,当想插入9(0009)时,9<50,向左走,再比较,9<25再向左走;在比较,9<18,再向左走,

往下遇到 "两个子节点为红色(13和19)" 的"黑色父节点"。

        变色过程:13和19变黑色,18变红色

        执行结果图:


2  在向下路途上的旋转

      执行时间点:插入节点前        

      解释:为什么旋转,因为在执行 "1在下行途中的颜色变换" 颜色变换后,可能会遇到红红冲突的情况,18和25都是红色,这时需要旋转来解决颜色冲突的问题。

旋转次数,又因为节点是 ’ 祖父节点的内侧子节点还是外侧子节点 ’ 而不同。

        假设我们称18为X,25为P,50为G(祖父)。

这里有个命名规则要注意,为什么我们把18命名为X,到底符合什么条件的节点我们把他命名为X呢X是一个特殊节点,一般是违反规则的节点。

      例如情况一我们把新插入的节点命名为x;

      情况二 我们把父节点和子节点发生“红红”颜色冲突时的子节点成为X,就像这里执行“1 在下行途中的颜色变换”后,18和25出现红红颜色冲突,子节点18命名为X。

  旋转过程:

      这个属于祖父节点的外侧子节点(其他情况见书),先25 50变色,然后以G(50)为顶点旋转,同时要把以27为根节点的整颗子树横移,成为50的左子节点。

执行结果图:


-----------------图2--------------------------

3 插入节点后的旋转

执行时间点:插入节点后

假如我们想在2图的基础上,9下面再插入5。要想符合红黑树规则,9和13需要变色(具体如何变色旋转见书),13变色后会和18“红红”颜色冲突,这时需要根据“2 在向下途中的旋转”进行操作吗?答案是否定的,注意“执行时间点”,2是在插入前执行,我们现在是在插入后,所以要按照3的变色旋转情况执行。9和13先变色,然后以13为顶点,右旋转即可。

执行结果图:


--------------图3--------------------

4 附

问:禅师,“1在下行途中的颜色变换” 和 “3插入节点后的旋转” 有淡淡的联系吗?

答:如果图2中13再有个红右子节点(15),那么就符合“1 在下行途中的颜色变换” 情况,我们只要直接用 1 方式处理即可。

问:禅师,图3的执行结果问题,假如我们想在2图的基础上,9下面再插入5,在查找插入点位置的过程中,会发现18和50为红,25为黑,按“1 在下行途中的颜色变换”的理论我们应该颜色变换,为什么你图3的结果图中18和50没改变颜色,你是不是想告诉我们要有一双发现问题的眼睛?

答:大意了,被你发现了。首先按照我上面讲的三种情况是绝对可以得到一棵正确的红黑数的,例如18和50红色是正确的,都变成黑色也是红黑树。其实按照我上文的步骤是先颜色变换,18和50变黑后,再接着执行"在9下面插入5”的操作。

但是为何图中的结果不是按照我上文的步骤呢?这是因为对于同一题,不同的人有不同的解决办法,有的书上介绍的是先变色再旋转,有的是先旋转然后把x赋值给祖父节点再判断有没有冲突。我自己懒得画图,就用网站上自动生成的图。

5 下篇 红黑树之java代码实现 http://blog.csdn.net/wabiaozia/article/details/78974861

博客所有文章目录:http://blog.csdn.net/wabiaozia

转载请表明链接:http://blog.csdn.net/wabiaozia/article/details/53216228


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值