所谓的红黑树(RB_tree)不仅是一个二叉搜索树,而且必须满足一下规则:
1):每个节点不是红色就是黑色
2):根节点是黑色
3):如果节点是红色,那么它的子节点必须是黑色
4):任一结点至NULL(树尾端)的任何路径,所含的黑节点数必须相同
根据规则4):那么新增结点必须是红色节点,根据规则3):新增结点的父结点必须是黑色![
插入结点
当我们插入一些点的时候,可能会违反红黑树的规则,那么我们就必须做出相应的调整
下面是红黑树的结点设计
typedef bool __rb_tree_color_type;
const __rb_tree_color_type __rb_tree_red=false;//红色为0
const __rb_tree_color_type __rb_tree_black=true;//黑色为1
struct __rb_tree_node_base{
typedef __rb_tree_color_type color_type;//定义颜色的类型
typedef __rb_tree_node_base *base_ptr;//基类指针类型
color_type color;//节点颜色 非红即黑
base_ptr parent;//RB树的许多操作 必须是父节点
base_ptr left;//指向左结点
base_ptr right;//指向右节点
static base_ptr minimum(base_ptr x){
while (x->left!=0) x=x->left;//一直向左走 就会找到最小值
return x;//这是二叉搜索树的特性
}
static base_ptr maximum(base_ptr x){
while(x->right!=0) x=x->right;//一直向右走 就会找到最大值
return x;
}
};
template <class Value >
struct __rb_tree_node:public __rb_tree_node_base//继承了基类结点
{
typedef __rb_tree_node<Value> * link_type;//这个指针可以指向基类的所有成员
Value value_filed ;//节点值
}
/*
为了更大的弹性 SGI将RB-tree迭代器实现为两层
*/
//基层迭代器
struct __rb_tree_base_iterator{
typedef __rb_tree_node_base::base_ptr base_ptr;//基类指针
typedef bidirectional_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
base_ptr node;//他用来与容器之间产生一个连接关系
//以下其实可以用于实现operator++内,因为再无其他处会调用此函数了
void increment(){
if(node->right!=0){//如果有右子节点 状况1
node=node->right;//向右走
while(node->left!=0)//然后就一直沿着左子树走到底
node=node->left;//即是解答 就相当于是那个叶子节点了
//一定要走到底部 叠加器也只是增加一个顶点 所以要找到最接近的那个顶点
}else{//没有右子节点 如果这个结点没有右子结点 ,那么就应该网上追溯
base_ptr y=node->parent;//找出父节点
while(node==y->parent)//如果现行节点本身是个右子节点
{
node=y;
y=y->parent;//如果本身一直是右子结点 那么就需要一直往上追溯 直到不再是右子结点为主
}
//此时的node可能指向了header 结点
if(node->right!=y)//此时的右子节点不等于此时的父节点
node=y;//此时的父节点即为解答
}
}
/*
注意:以上判断“若此时的右子节点不等于此时的父节点”,是为了应付一种特殊情况、
我们欲寻找根节点的下一节点,而恰巧根节点无右子节点
当然 以上的特殊做法必须配合RB_tree根节点与特殊节点之header之间的特殊关系
*/
void decrement(){
if(node->color==__rb_tree_red &&//如果是红节点
node->parent->parent==node)//父节点的父节点等于自己
node=node->right;//状况1 右子节点等于自己
//以上情况发生于node为header时(也就是node为end()时)
//注意 header的右子节点即mostright 指向整棵树的max节点
else if(node->left!=0){//如果有左子节点
base_ptr y=node->left;//令y指向左子节点
while(y->right!=0)//当y有右子节点时
y=y->right;//一直往右子节点走到底
node=y;
}
else{//既非根节点 亦无左子节点
base_ptr y=node->parent;//状况三 找出父节点
while(node==y->left){//当先行节点身为左子节点
node=y;//一直交替往上走 ,直到现行节点
y=y->parent;//不为左子节点
}
node=y;//此时的父节点就是答案
}
}
};
//RB_tree的正规迭代器
template<class Value,class Ref,class Ptr>
struct __rb_tree_iterator:public: __rb_tree_base_iterator{
typedef Valu