赞
踩
前言:本文转载自点击这里阅读原文
另外:本文最好拿笔+草稿纸一边看一边按照规则进行演变,本文的过程可能和你演变的不一样,没关系,看懂思想,然后根据答案去反推,去思考,我相信你会有所收获的
红黑树就是一种平衡二叉树,说它平衡的意思是它不会出现左子树与右子树的高度之差不会大于1,左子树和右子树保持一种平衡的关系。
红黑树主要有以下5种特性:
如下图就是一个典型的红黑树:
很多同学可能会觉得惊讶,天啊这个条条框框的也太多了吧。然而正是因为这些规则,才能保证红黑树的自平衡。最长路径不超过最短路径的2倍。
当插入和删除节点,就可能会对平衡造成破坏,这时候就需要对树进行调整,从而重新达到平衡。那么什么情况下会破坏红黑树的规则呢?
让我们看下面的图
向原来的红黑树插入值为14的新节点,由于父节点15是黑色节点,所以这种情况没有破坏结构,不需要做任何的改变。
向原树插入21呢?看下图:
由于父节点22是红色节点,因此这种情况打破了红黑树的规则4(每个红色节点的俩个子节点都是黑色的),此时必须对树进行调整使其满足红黑树的定义。那么该如何调整呢?有两种方式【变色】和【旋转】,其中【旋转】又分为【左旋转】和【右旋转】。
ps:这里可能有人会觉得新插入节点21的应该是一个黑色节点,其实应该才是对的,但是,如果此时插入的节点21是黑色节点的话,那么这棵树同样是不合法的,因为此时这棵树不满足红黑树的规则5(从任意节点到其每个叶子节点的所有路径都包含相同的黑色节点),因此同样是需要调整的。注意,图中标注为NIL的才是叶子节点,这里我觉得把节点21标为红色应该是原文的作者想岔了,如果我的想法有误还请看懂的小伙伴留言提醒一下。虽然我觉得节点21不应该是红色的,不过作者下面的想法还是可以作为学习使用
【变色】:
为了符合红黑树的规则,会把节点由红变黑或者由黑变红。下图展示的是上文红黑树的部分,需要注意节点25并非是根节点。因为21和22都是红色,不符合规则4(每个红色节点的俩个子节点都是黑色的),所以我们把22由红变黑:
但是呢,这样一来又无法满足规则5(从任意节点到其每个叶子节点的所有路径都包含相同的黑色节点),所以需要把25由黑变红,看下图:
你以为这样子就可以结束了?天真,因为此时25和27又是连个连续的红色节点(规则4::每个红色节点的俩个子节点都是黑色的),所以我们需要把27由红变黑,如下图:
好了,大功告成,终于告一段落了,看起来舒服多了,接下来让我们来看看【旋转】是个什么东西吧
【旋转】之【左旋转】
也就是逆时针旋转两个节点,是父节点被自己的右孩子取代,而自己成为自己的左孩子 ,定义看起来乱糟糟的,直接看图吧:
【旋转】之【右旋转】
顺时针旋转两个节点,使得自己成为左孩子的右孩子,原来的左孩子成为自己的父节点,原来左孩子的右孩子成为自己的右孩子,好复杂,直接看图吧:
看起来这么复杂,到底怎么用呢?确实有点小复杂,我们讲下典型的例子,大家参考下:
以刚才插入21节点的例子:
首先我们需要做的是变色,把节点25以及下方的节点变色:
由于17和25是连续的红色节点,那么把节点17变黑吗?这样是不行的(规则5)而且根据规则2(根节点必须是黑色的),也不可能把13变成红色,变色已经无法解决问题了,所以只能进行旋转了。13当成X,17当成Y,左旋转试试看:
由于根节点必须是黑色,所以需要变色,结果如下图:
此时,有两条路径17-13-8-1-6-null上的黑色节点数和其他路径不一样,不符合规则5,这个时候需要把13当做X,8当做Y,进行右旋转:
最后根据规则变色:
这样一来,我们终于结束啦,终于完全符合规则了。
总结:
这篇文章虽然过程似乎存在错误,但是结果是正确的,总体来说还是不错的,感谢大佬的分享和制作。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。