红黑树
1.概述
定义
由红、黑两色节点组成的二叉搜索树若满足以下条件,即为红黑树 (red-black tree):
(1) 树根始终为黑色
(2) 外部节点均为黑色
(3) 其余节点若为红色,则其孩子节点必为黑色
(4) 从任一外部节点到根节点的沿途,黑节点的数目相等
从以上条件可得:红节点均为内部节点,且其父节点及左、右孩子必然存在。红节点之父必为黑色,因此树中任一通路都不含相邻的红节点。
在从根节点通往任一节点的沿途,除去根节点本身,沿途所经黑节点的总数称作该节点的黑深度(black depth)——根节点的黑深度为0,其余依此类推。
在从任一节点通往其任一后代外部节点的沿途,沿途所经黑节点的总数称作该节点的黑高度(black height)。
如此,所有外部节点的黑高度均为0,其余依此类推。
(2,4)-树
自顶而下逐层考查红黑树各节点。每遇到一个红节点,都将对应的子树整体提升一层,从而与其父节点(必黑)水平对齐,二者之间的联边则相应地调整为横向。此时,若将原红黑树的节点视作关键码,沿水平方向相邻的每一组(父子至多三个)节点即恰好构成4阶B-树的一个节点。
以下将不再严格区分红黑树中的节点及其在(2,4)-树中对应的关键码。当然,照此理解,此时的关键码也被赋予了对应的颜色。对照红黑树的条件,(2,4)-树中的每个节点应包含且仅包含一个黑关键码,同时红关键码不得超过两个。而且,若某个节点果真包含两个红关键码,则黑关键码的位置必然居中。
2.红黑树接口定义
基于BST模板类,可派生出RedBlack模板类
#include "../BST/BST.h" //基于BST实现RedBlack
template <typename T> class RedBlack : public BST<T> { //RedBlack树模板类
protected:
void solveDoubleRed(BinNodePosi(T) x); //双红修正
void solveDoubleBlack(BinNodePosi(T) x); //双黑修正
int updateHeight(BinNodePosi(T) x); //更新节点x的高度
public:
BinNodePosi(T) insert(const T& e);
bool remove(const T& e);
// BST::search()等其余接口可直接沿用
};
代码8.13 基于BST定义的红黑树接口
这里还需使用此前二叉树节点模板类BinNode中预留的两个成员变量height和color。
仿照AVL树的实现方式,可借助辅助宏来检查节点的颜色以及判定是否需要更新(黑)高度记录,如此可大大简化相关算法的描述。
#define IsBlack(p) (!(p) || (RB_BLACK == (p)->color)) //外部节点也视作黑节点
#define IsRed(p) (!IsBlack(p)) //非黑即红
#define BlackHeightUpdated(x) ( \
(stature((x).lChild) == stature((x).rChild)) && \
((x).height == (IsRed(&x) ? stature((x).lChild) : stature((x).lChild) + 1)) \
) //RedBlack高度更新条件