[关闭]
@chenxuxiong 2016-05-26T16:13:19.000000Z 字数 2142 阅读 634

红黑树

数据结构


Java 实现的红黑树

备注:本文中所有关于红黑树中的示意图采用白色代表红色。黑色节点还是采用了黑色表示。

根据性质 5:红黑树从根节点到每个叶子节点的路径都包含相同数量的黑色节点,因此从根节点到叶子节点的路径中包含的黑色节点数被称为树的“黑色高度(black-height)”。

性质 4 则保证了从根节点到叶子节点的最长路径的长度不会超过任何其他路径的两倍。假如有一棵黑色高度为 3 的红黑树:从根节点到叶节点的最短路径长度是 2,该路径上全是黑色节点(黑节点 - 黑节点 - 黑节点)。最长路径也只可能为 4,在每个黑色节点之间插入一个红色节点(黑节点 - 红节点 - 黑节点 - 红节点 - 黑节点),性质 4 保证绝不可能插入更多的红色节点。由此可见,红黑树中最长路径就是一条红黑交替的路径。

插入后的修复,插入维护

在插入操作中,红黑树的性质 1 和性质 3 两个永远不会发生改变,因此无需考虑红黑树的这两个特性。

这种颜色调用和树旋转就比较复杂了,下面将分情况进行介绍。在介绍中,我们把新插入的节点定义为 N 节点,N 节点的父节点定义为 P 节点,P 节点的兄弟节点定义为 U 节点,P 节点父节点定义为 G 节点。

下面分成不同情形来分析插入操作

情形 1:新节点 N 是树的根节点,没有父节点

在这种情形下,直接将它设置为黑色以满足性质 2。

情形 2:新节点的父节点 P 是黑色

在这种情况下,新插入的节点是红色的,因此依然满足性质 4。而且因为新节点 N 有两个黑色叶子节点;但是由于新节点 N 是红色,通过它的每个子节点的路径依然保持相同的黑色节点数,因此依然满足性质 5。

情形 3:如果父节点 P 和父节点的兄弟节点 U 都是红色

在这种情况下,程序应该将 P 节点、U 节点都设置为黑色,并将 P 节点的父节点设为红色(用来保持性质 5)。现在新节点 N 有了一个黑色的父节点 P。由于从 P 节点、U 节点到根节点的任何路径都必须通过 G 节点,在这些路径上的黑节点数目没有改变(原来有叶子和 G 节点两个黑色节点,现在有叶子和 P 两个黑色节点)。

经过上面处理后,红色的 G 节点的父节点也有可能是红色的,这就违反了性质 4,因此还需要对 G 节点递归地进行整个过程(把 G 当成是新插入的节点进行处理即可)。

图 7 显示了这种处理过程:
此处输入图片的描述

备注:虽然图绘制的是新节点 N 作为父节点 P 左子节点的情形,其实新节点 N 作为父节点 P 右子节点的情况与前图完全相同。

情形 4:父节点 P 是红色、而其兄弟节点 U 是黑色或缺少;且新节点 N 是父节点 P 的右子节点,而父节点 P 又是其父节点 G 的左子节点。

在这种情形下,我们进行一次左旋转对新节点和其父节点进行,接着按情形 5 处理以前的父节点 P(也就是把 P 当成新插入的节点即可)。这导致某些路径通过它们以前不通过的新节点 N 或父节点 P 的其中之一,但是这两个节点都是红色的,因此不会影响性质 5。
图 8 显示了对情形 4 的处理:
此处输入图片的描述

备注:图 11.29 中 P 节点是 G 节点的左子节点,如果 P 节点是其父节点 G 节点的右子节点,那么上 面的处理情况应该左、右对调一下。

情形 5:父节点 P 是红色、而其兄弟节点 U 是黑色或缺少;且新节点 N 是其父节点的左子节点,而父节点 P 又是其父节点 G 的左子节点。

在这种情形下,需要对节点 G 的一次右旋转,在旋转产生的树中,以前的父节点 P 现在是新节点 N 和节点 G 的父节点。由于以前的节点 G 是黑色,否则父节点 P 就不可能是红色,我们切换以前的父节点 P 和节点 G 的颜色,使之满足性质 4,性质 5 也仍然保持满足,因为通过这三个节点中任何一个的所有路径以前都通过节点 G,现在它们都通过以前的父节点 P。在各自的情形下,这都是三个节点中唯一的黑色节点。

图 9 显示了情形 5 的处理过程:

此处输入图片的描述

备注:图 中 P 节点是 G 节点的左子节点,如果 P 节点是其父节点 G 节点的右子节点,那么上面的处理情况应该左、右对调一下。

参考http://www.cnblogs.com/liqizhou/archive/2012/09/27/java%E4%B8%ADtreemap%E5%92%8Ctreeset%E5%AE%9E%E7%8E%B0%E7%BA%A2%E9%BB%91%E6%A0%91.html

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注