一.红黑树的介绍
红黑树是一种自平衡二叉树,红黑树和AVL树一样都对插入时间、删除时间和查找时间提供了最好可能的最坏情况担保。红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。
二.红黑树的性质
1. 节点是红色或黑色。
2. 根是黑色。
3. 所有叶子都是黑色(这里需要将null看作叶子节点,且认为时黑色)。
4. 从每个叶子到根的所有路径上不能有两个连续的红色节点。
5. 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
三.红黑树的插入与删除
这里涉及到需要左旋,右旋的概念。
先来看左旋:
右旋:
插入----- 红黑树的插入比二叉树复杂,前面过程是一样的,像二叉树一样先找到插入节点位置,插入新节点。然后再进行红黑树的性质修复。
插入后的修复,要分几种情况:
树为空,我们没必要调整,直接讲新添加的节点作为根,并将颜色置为黑色:
如果添加节点的父节点为黑色,这样并不会违反红黑树的性质,所以不必调整:
当新节点的父节点为红色时,又分为3种情况:
假设z为新加的节点,y为z的叔父节点(父节点的兄弟节点)
(1) z的叔父节点y是红色的。
这时只需要将父,叔节点置为黑色,将祖父节点置为红色,然后以祖父节点递归上面的调整过程
(2)z的叔父节点y是黑色的,而且z是一个右节点
这时以z父节点做一个左旋转,旋转后变成情况(3)
(3)z的叔父节点y是黑色的,而且z是一个左节点
这时以z父节点做一个右旋转,再做一次情况(1)的颜色变换,调整结束。
删除----- 红黑树的删除比较复杂,我们还是用图说话。
设x为删除后替换的新节点,w为x的兄弟节点,→表示删除指针,y表示真正要删除的节点(在二叉树中,删除一个节点,我们会找此节点右子树最小的点替换,那么这个替换点就是真正要删除的节点,x为y的孩子节点)
删除后的修复,也分几种情况:
y为红节点
那么y肯定是一个叶子节点,直接删除y节点就可以了。调整结束
y为黑节点,x为红节点
此时用x替换y,把x替换成黑色即可。调整结束
x,y都是黑色时候,分为4种情况:
(1) w是红色
这时要将父节点左旋转,旋转后1又变成了x的新的w,是黑色的,转到下面几种情况继续调整。
(2)w是黑色,而且w两个儿子都是黑色的。
这时将父节点(调整前父节点可能是红色也可以是黑色,用青色来表示)变黑,w变红;如果父调整前是红节点,那么调整结束;如果父调整前是黑节点,那么将继续调整,删除指向父节点
(3)w是黑色,而且w左孩子红色,右孩子黑色
这时交换w和w.left的颜色,然后以w.left为节点右旋,变成情况4继续调整
(4)w是黑色,而且w右孩子红色
这时交换父节点和w的颜色,然后以父为节点左旋,调整结束 一个
四.算法分析
定理:一棵有n个节点的红黑树的高度至少为2lg(n+1)
证明:设任意一节点x的黑节点高度为hb(x),首先证明以x为根的子树至少2^hb(x)-1。这个可以用归纳法证明,我在这里不展开证明,想了解的话可以看看算法导论红黑树一节。在这里我给出不是很严谨的解释:
因为红黑树可以看做一棵2-3树,把所有红节点收起来,和父节点的黑节点组成一个3-节点,其余的就是2-节点。2-3树是一棵完美平衡的二叉树,高为h的2-3树包含的节点数大于等于高度为h的满二叉树的节点数,即至少有2^h-1个节点,所以以x为根的子树至少2^hb(x)-1。
设h(x)为树高,因为从根到叶子任何一条路径上黑节点至少都超过总结点的一半所以 hb(x) >=h(x)/2, 所以 n >=2^h/2-1 所以得出 n>=2lg(n+1)。
插入算法
由于红黑树的高度为lgn,所以插入算法在查找的时候回消耗O(lgn),insert的时间复杂度也是O(lgn)。在插入修复的过程中,可以往上看下插入的图,最多只需要2次旋转就可以调整结束。
删除算法
和插入算法一样,delete的时间复杂度也是O(lgn)。我们重点看下删除修复的过程,情况(1),(3),(4)会发生旋转,最多发生3次旋转后调整结束。
红黑树和AVL树对比
红黑树比avl树的性能优势,主要在于插入或删除后修复过程中的旋转次数,红黑树插入最多会发生2次旋转,删除最多会发生3次旋转,而avl树会发生更多次的旋转,在时间复杂度都是O(lgn)的情况下,红黑旋转的次数更少具有一定的性能优势。