【数据结构】红黑树

相对AVL树这种高度平衡的树来说红黑树是一种弱平衡的二叉查找树,相对来说红黑树的平衡没有AVL树那么平衡,但是红黑树所需的自平衡才做也相对要少。红黑树的时间复杂度为O(log)。
Rudolf Bayer 与 1972 年发明了另一种改进后的排序二叉树:红黑树,他将这种排序二叉树称为”对称二叉 B 树”,而红黑树这个名字则由 Leo J. Guibas 和 Robert Sedgewick 于 1978 年首次提出。

  • 性质
  • 推论
  • 平衡方式
  • 平衡示例

性质 & 定义

性质 1:每个节点要么是红色,要么是黑色。
性质 2:根节点永远是黑色的。
性质 3:所有的叶节点都是空节点(即 null),并且是黑色的。
性质 4:每个红色节点的两个子节点都是黑色。(从每个叶子到根的路径上不会有两个连续的红色节点)
性质 5:从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点。

上述5条性质中,其中三条不难理解,后续两条相对来说比较难理解,需要结合红黑树的操作,后续会一一描述。

红黑树的示意

推论

黑色高度:从性质5我们可以看出,红黑树主要是采用黑色节点的数量作为树的高度,一般称为黑色高度

从性质4我们可以看出,红色节点其子节点必须是黑色节点,而黑色节点的子节点可以是黑色节点。再结合性质5黑色节点相同的性质我们可以看出最短路径那肯定是全部都是黑色的节点的路径,而最长路径肯定是红黑相间的路径,所以在红黑树中,可以得到以下推论。

推论1:最短路径不能超过最长路径的两倍

由于红黑树是以黑色节点的数量作为树的高度计算因素,那么我们在新插入节点时如果插入的是黑色节点,那么我们会直接破坏树的平衡。所以我们在插入节点时,会插入红色节点,并通过变色和旋转来维持树的平衡。

平衡方式

旋转:通过左旋或者右旋节点进行平衡。

旋转可以参考AVL树的旋转介绍 AVL树

变色:通过改变父亲节点、叔叔节点以及祖父节点的颜色来达成平衡。

平衡示例

情况1:根节点为空

如果整棵树为空,那么新插入的节点从红色变为黑色即可(参照性质2)。

情况2:插入节点N后,父节点为黑色

在插入节点后,如果父节点为黑色,那么我们什么都不用做,直接插入即可。在这种情况下符合所有性质。

情况3:插入节点N后,父节点为红色。

情况3.1:叔叔节点为红色

在叔叔节点是红色的情况下,只要将父节点和叔叔节点同时变为黑色即可。这样可以满足【性质4】因为从红色变为黑色没有子节点颜色的限制。也满足【性质5】,因为左树和右树的节点同时变为黑色,那么相当于左树和右树都增加了一个高度,那么这个树也就平衡了。

红黑树变色

情况3.2:叔叔节点不存在

在叔叔节点不存在的情况下,需要对树进行旋转,如下图所示。原本是【节点5】作为主节点,旋转之后【节点4】作为主节点【节点5】作为【节点4】的右节点。并对【节点4】和【节点5】进行变色

叔叔节点不存在的情况

情况3.3:叔叔节点为黑色

下述图片的情况是不存在的,本身不符合【性质5】,只有【图6】这种情况才存在叔叔节点是黑色的情况。


图5:不存在的情况
图6:存在的情况

在上述图6中,尝试插入新节点后,如下图所示【节点2】和【节点4】和【节点3】如【情况3.1】所述的进行变色,在变色完成之后【节点3】以及子树已经符合【性质4】和【性质5】达到平衡,但这棵树是不平衡的。所以还需要继续向上进行处理。


红黑树5.png

在【节点3】进行上溯的时候【节点5】可以变色【节点10】无法进行变色【节点12】也无法进行变色。也就是说【节点10】的右树无法多出一个黑色节点,并达到平衡。所以这个时候需要进行旋转。


红黑树7.png

后续要怎么旋转呢,我们之前说到这颗树【节点3】以及子树本身已经平衡,那么我们从【节点3】开始对其进行旋转。我们以【节点3】的父节点【节点5】为中心进行旋转,【节点5】作为根目录【节点10】作为【节点5】右节点。【节点7】转换为节点【节点10】的左节点。然后对【节点5】、【节点10】进行变色。变换后如下图所示,并且完全达成平衡。
红黑树8.png

上述情况是在左子结点发生的,如果是右侧子节点插入,那么是从相反的方式处理
另外如果是左子树的右侧节点,如果涉及到旋转那么先把当前节点左旋,之后再进行其他旋转操作,如下图所示。

右侧节点处理

以上基本上是红黑树的一些基本的情况介绍,介绍相对简略,如果错漏,请指出。

你可能感兴趣的:(【数据结构】红黑树)