一,红黑树介绍
什么是红黑树?为什么需要红黑树?
对数据集合进行 查找、插入、删除、找最大结点、找最小结点、找前驱/后继结点 是一种很常见的需求,那如何找到一种数据结构来高效地实现前面的各个基本操作呢?根据对各种树 进行了的基本介绍。AVL树虽然能保证各种基本操作在O(logN)内实现,但是它的旋转操作复杂,更常用的是红黑树。
红黑树就是一棵特殊的二叉查找树。它能保证在最坏的情况下,上面列出的所有基本操作的时间复杂度为O(logN)
那它是如何做到这一点的呢?下面列出的红黑树的性质就保证了对数时间复杂度。
①每个结点要么是红的,要么是黑的
②根结点是黑的
③每个叶结点(NIL)是黑的--注意:这里的叶结点与平常讨论的树的叶结点不同。这里的叶结点是数据域为NIL的结点,而平常说的叶结点是:它的左右孩子为NIL的结点。
④若结点是红的,则它的儿子都是黑的
⑤对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点
上面的五点性质保证了红黑树的高度是logN,从而,保证了所有的基本操作的时间复杂度是O(logN)
二,红黑树为什么能保证各项基本操作的时间复杂度为对数级O(logN)
现在来证明为什么红黑树的高度是logN。
证明:一棵有 n 个内结点的红黑树的高度至多是 2log(n+1)
叶结点:数据域为NIL的结点。内结点(非叶结点):数据域不为NIL的结点。红黑树中每个结点有五个域(字段):①颜色 ②数据域(key) ③左指针 ④右指针 ⑤父结点指针
首先定义一个黑高度概念:从某个结点 x 出发,到达一个叶结点的任意一条路径上,黑色结点的个数 称为黑高度。记为 bh(x)
首先用数学归纳法可以证明:以 结点 x 为根的子树中至少包含 2bh(x) -1 个内结点。
其次,假设红黑树的高度为h(根结点的高度为0),由性质④可知:从根结点(不包括根)到叶结点的任一简单路径上至少有一半的结点是黑色的,从而根的黑高度至少是 h/2
再根据上面数学归纳法的结论:红黑树的根结点的子树中至少包含 2h/2-1 个内结点。
从而有: n >= 2h/2 -1, 得出 h <= 2log(n+1),从而证明了红黑树的高度是O(logN)
这种情况下:n=3,h=1,根的黑高度为1
这种情况下:n=15,h=3,根的黑高度为1
三,红黑树的基本操作
①插入操作--具体实现细节就不讨论了
插入部分主要分成三大步骤:
第一步:与二叉查找树中插入一个结点类似,将待插入的结点与红黑树中各个结点递归比较,若待插入的结点权值大,则插入到右子树中;若待插入的结点权值小,则插入到左子树中。
第二步:由第一步可知,待插入的结点现在已经放到了红黑树的最后一层,将该结点标记为红色。
第三步:对插入的结点进行调整,以保证红黑树的性质不被破坏。调整主要包括各种旋转操作。而且旋转操作只会改变指针的指向,因此旋转的时间复杂度为O(1)
②删除操作
删除一个结点时,也会破坏红黑树的性质,因此,也需要进行调整。具体细节参考《算法导论》