标签:
一、概念
红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结点的颜色,可以是RED或BLACK。通过对任何一条从根到叶子的简单路径上各个结点的颜色进行约束,红黑树确保没有一条路径会比其他路径长2倍,因而是近似于平衡的。
二、定义
一棵红黑树是满足下面红黑性质的二叉搜索树:
1、每个结点或是红色,或是黑色;
2、根节点是黑色的;
3、每个叶节点(NIL)是黑色的;
4、如果一个结点是红色的,则它的两个子结点都是黑色的;
5、对每个结点,从该结点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点(此黑色结点的数目称为黑高)。
三、和平衡二叉树的区别
平衡二叉树是完全平衡的,而红黑树是局部平衡的,能确保没有一条路径会比其他路径长2倍,并且调整少,性能高,所以得到广泛应用,在STL里map和set都由红黑树实现。
四、节点定义
enum node_color{RED,BLACK};
typedef struct RBnode
{
int key;//数据信息
struct RBnode *left;//左孩子
struct RBnode *right;//右孩子
struct RBnode *p;//父节点
enum node_color color;//结点颜色
}五、示例(图中所有空指针指向叶结点NIL)
六、旋转
目的:对红黑树进行插入和删除,可能会导致该树不在满足红黑树的性质,为了维护红黑树的性质,必须要改变树中某些结点的颜色以及指针结构。改变指针结构即通过旋转来完成,这是一种能保持二叉搜索树性质的搜索树局部操作。
1、左旋(LEFT_ROTATE)
图示:由三部完成该操作。
代码:
//将结点x左旋
RBnode *LEFT_ROTATE(RBnode *T, RBnode *x)
{
RBnode *y;
y=x->right;//set y
//step1:tunrn y's left subtree into x's right subtree
x->right=y->left;
if(y->left!=NIL)
y->left->p=x;
//step2:link x's parent to y
y->p=x->p;
if(x->p==NIL)
T=y;
else if(x==x->p->left)
x->p->left=y;
else
x->p->right=y;
//step3:put x on y's left
y->left=x;
x->p=y;
return T;
}
代码:
//将结点x右旋
RBnode *RIGHT_ROTATE(RBnode *T, RBnode *x)
{
RBnode *y;
y=x->p;//set y
//step1:tunrn x's right subtree into y's left subtree
y->left=x->right;
if(x->right!=NIL)
x->right->p=y;
//step2:link y's parent to x
x->p=y->p;
if(y->p==NIL)
T=x;
else if(y==y->p->left)
y->p->left=x;
else
y->p->right=x;
//step3:put y on x's right
x->right=y;
y->p=x;
return T;
}插入操作与上一篇博文二叉排序树插入操作基本相同,除了细节之处稍有改变。
代码:
//在红黑树T上插入结点z
RBnode *RB_INSERT(RBnode *T, RBnode *z)
{
RBnode *x;
RBnode *y;
y=NIL;
x=T;
while(x!=NIL)
{
y=x;
if(z->key < x->key)
x=x->left;
else
x=x->right;
}
z.p=y;
if(y==NIL)
T=z;
else if(z->key < y->key)
y->left=z;
else
y->right=z;
z->left=NIL;
z->right=NIL;
z->color=RED;
RB_INSERT_FIXUP(T,z);
}八、染色和调整
由于插入操作可能破坏红黑树性质,通过RB_INSERT_FIXUP(T,z)函数调整结点颜色和树的结构,使其保持红黑性质。——明晚继续完善
标签:
原文地址:http://blog.csdn.net/xiaowang627/article/details/51339959