红黑树

来源:互联网 发布:360急速浏览器 优化版 编辑:程序博客网 时间:2024/06/04 00:29

定义:
(1)二叉搜索树;
(2)每个节点都有颜色,不是红色就是黑色,NULL节点视为黑色;
(3)根节点是黑色;
(4)不能有两个连续的红色节点;
(5)任意节点延伸到其子叶节点的路径上的黑色节点个数必须相同。
诞生原因:随机插入、删除等操作时二叉搜索树的平衡性会变得比较差(最坏的情况例如所有节点只有右子节点),希望(1)改善平衡性;(2)寻求好的调整方法降低这种改善所付出的代价。

注意:红黑树的定义改善了平衡性,而红黑树的插入、删除等操作的原则是经过一系列操作之后满足红黑树的定义,并且使得付出的代价最小,也就是使得操作的步骤最少。

红黑树的插入操作

个人理解,关键的原则就是:单次插入,(1)调整平衡时的操作步骤最少,影响区域最小(2)把节点颜色和数值大小分开考虑
为方便表示,把插入位置的父节点称为P,P的父节点称为G,P的兄弟节点称为S,把插入位置的节点称为X。
情况一:插入位置的父节点为黑色

插入后把颜色设置为红色。假设设置为黑色,那么就不满足红黑树定义的(5),于是需要调整树结构,不符合我总结的原则。
情况二:插入位置的父节点为红色

设置为黑违反(5);但是我们发现无论插入红色还是黑色,对于其父节点来说,仍然满足红黑树定义,于是我们需要往上找,找出最近一个不满足红黑树定义的点,并且希望作出调整操作以后,影响不会再往上延伸,也就是希望影响区域最小。

此时爷爷节点必定为黑色,于是需要考虑的情况就是父节点的兄弟节点。
(1)S为黑色
我们希望调整平衡时的操作步骤最少,影响区域最小,于是G节点仍然要设置成黑色(不管这个节点数值还是不是和原来一样,注意原则二),如果G节点设置为红色,那么G节点的父节点如果为红色,影响区域就扩大了,注意原则一。那么我们是否可以做到在G节点为黑的情况下,经过一系列调整,满足红黑树的定义呢?确实可以。(这里以P为G的左子节点为例)
这里写图片描述
(2)S为红色
G节点在调整之后是否还可以是黑色呢?如果G为黑色,为了满足红黑树的定义(5),S和P都不能调整为黑色,那么导致X一旦插入,无论是黑色还是红色,都不能满足定义。因此G要调整为红色,G一旦为红色,G的父节点如果为黑色,那么调整结束;否则,影响继续往上延伸;为了不使影响这样延伸,侯捷的《STL源码分析》中指出,当遇到一个层上两个节点都为红色时,把这两个节点的颜色设置为黑色 ,把他们的父节点颜色设置为红色,如果是根节点的两个子节点为红色,则把两子节点设置为黑色,而根节点颜色依然是黑色。试想如果这件事情只在插入位置的上两层这么调整颜色,显然会使影响扩大到更上面的层,于是,从根节点开始,在插入的路径上发现这样的情况就直接作出调整,即从上往下调整。经过这样调整,S和P都为红色的情况就不复存在。
这里写图片描述

总结:我们发现,插入时,最终要调整的情况就是P为红色,S为黑色,并且从图中得知(该例中P为G的左子节点,S为G的右子节点),无论X是插入到P的左子节点还是右子节点,调整后这四个位置(注意指的是位置):X,P,S,G的颜色是确定的。原因就是在两个黑色节点中“加入”一个红色节点,依然满足红黑树的定义;另外再考虑这四个位置上元素的值:请让我们这样去思考,二叉树的形式相当于有序排列(横向)加入了高低的属性(竖直)。
这里写图片描述
这里写图片描述

从上图这个例子,结合前面的红黑树调整示意图,在P为G的左子节点,S为右子节点的前提下,我们可以清晰地看到 数值2对应的节点最终成为了G节点,这里就好似1-2-3-4是相连的,然后我把2提起来,并把“-”换成“->”,这个也就是我前面所说的在两个黑色节点中插入一个红色节点。

0 0