红黑树概述
历史上 AVL 树流行的另一变种是红黑树(red-black tree)。对红黑树的操作能保证在最坏情况下动态几何操作的时间为 O(logN) 。之前介绍过AVL 树,该树都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。但 RB-Tree 出来之后,便很少有应用场合用到 AVL 。
这里在探索STL源码时学习红黑树的,由于STL中的关联式容器默认的底层实现都是红黑树,以及 Linux 内核中包括进程队列等结构也是基于红黑树的。所以有必要掌握红黑树的实现原理和源码实现。
红黑树是二叉查找树,但在每个节点上增加了一位存储位表示该节点的颜色,具体可以是 RED 或 BLACK。通过对任一条从根到叶子的路径上各节点着色方式的限制,红黑树确保了没有一条路径会比其他路径长到两倍,因而基本上是平衡的。它所追求的的是局部平衡而不是AVL树中的非常严格的平衡。
红黑树在二叉查找树的基础上还必须满足以下着色规则:
- 每个节点不是红色就是黑色
- 根节点为黑色
- 如果节点为红,其子节点必须为黑(一条路径上不能出现连续的两个红色节点)
- 任一节点至NULL(树尾端)的任何路径,所含之黑节点数必须相同
根据规则4,新增节点必须为红;根据规则3,新增节点之父点必须为黑。当新节点根据二叉查找树的规则(键值大小)到达其插入点,却未能符合上述条件,就必须调整颜色并旋转树形。AVL 树插入节点后如果不满足其平衡条件,需要旋转树形。红黑树并不是基于 AVL 树的,它是在二叉查找树的基础上。
那么红黑树的基本平衡又是如何保证的呢?红黑树的着色法则,根据上面的规则,一条路径上不能出现连续的两个红色节点,必须有黑色节点间隔开来,然后红黑树的每条路径中所含黑色节点的数目必须相同,这样就限制每条路径之间的高度差,从而达到接近平衡的目的。