1. 红黑树的性质
树中每个节点包含5个属性:color,key,left,right和p.如果一个节点没有子节点或父节点,则该节点相应指针属性的值为NIL.
一棵红黑树是满足下面红黑性质的二叉搜索树:
1). 每个节点或是红色的,或是黑色的.
2). 根节点是黑色的.
3).每个叶节点(NIL)是黑色的.
4). 如果一个节点是红色的,则它的两个子节点都是黑色的.
5). 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点.
2. 旋转
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <limits.h>
typedef struct RBTREE{
int color; //0为红,1为黑
int data;
struct RBTREE *lchild;
struct RBTREE *rchild;
struct RBTREE *parent;
}RBTree;
//左旋转
void leftRotate( RBTree *rbtree, RBTree *x );
//右旋转
void rightRotate( RBTree *rbtree, RBTree *y );
//插入结点
void rbInsert( RBTree *rbtree, int value );
//删除节点
int rbDelete( RBTree *rbtree, int value );
//查找结点
RBTree *rbSearch( RBTree *root, RBTree *rbtree, int value );
//打印红黑树
void rbShowTree( RBTree *rbtree );
//辅助插入结点着色函数
void rbInsertFixup( RBTree *rbtree, RBTree *z );
//辅助删除节点着色函数
void rbDeleteFixup( RBTree *rbtree, RBTree *x );
//将子树v移植到子树u中
void rbTransplant( RBTree *rbtree, RBTree *u, RBTree *v );
//红黑树中的最小值
RBTree *rbtreeMinimum( RBTree *root, RBTree *rbtree );
//红黑树的最大值
RBTree *rbtreeMaximum( RBTree *root, RBTree *rbtree );
//查找后继结点
RBTree *rbtreeSuccessor( RBTree *rbtree, RBTree *x );
int main( void )
{
int i = 0;
RBTree *rbtree = ( RBTree * )malloc( sizeof( RBTree ) );
RBTree *NIL = ( RBTree * )malloc( sizeof( RBTree ) );
NIL->color = 1;
NIL->data = INT_MIN;
NIL->lchild = NIL->rchild = NIL->parent = NULL;
rbtree->color = 0;
rbtree->data = INT_MIN;
rbtree->lchild = NIL;
rbtree->rchild = rbtree->parent = NULL;
rbInsert( rbtree, 11 );
rbInsert( rbtree, 2 );
rbInsert( rbtree, 14 );
rbInsert( rbtree, 1 );
rbInsert( rbtree, 7 );
rbInsert( rbtree, 15 );
rbInsert( rbtree, 5 );
rbInsert( rbtree, 8 );
rbInsert( rbtree, 4 );
rbInsert( rbtree, 9 );
printf("the tree is:\n");
rbShowTree( rbtree->rchild );
if ( rbtree->lchild != rbSearch( rbtree, rbtree, 5 ) ){
printf("\n5 is in the tree\n");
}
else{
printf("\n5 is not in the tree\n");
}
rbDelete( rbtree, 5 );
rbDelete( rbtree, 7 );
rbDelete( rbtree, 9 );
printf("after delete, the tree is:\n");
rbShowTree( rbtree->rchild );
if ( rbtree->lchild != rbSearch( rbtree, rbtree, 5 ) ){
printf("\n5 is in the tree\n");
}
else{
printf("\n5 is not in the tree\n");
}
return 0;
}
void leftRotate( RBTree *rbtree, RBTree *x )
{
RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
y = x->rchild;
x->rchild = y->lchild;
if ( y->lchild != rbtree->lchild ){
y->lchild->parent = x;
}
y->parent = x->parent;
if ( x->parent == rbtree->lchild ){
rbtree->rchild = y;
}
else if ( x == x->parent->lchild ){
x->parent->lchild = y;
}
else{
x->parent->rchild = y;
}
y->lchild = x;
x->parent = y;
}
void rightRotate( RBTree *rbtree, RBTree *y )
{
RBTree *x = ( RBTree * )malloc( sizeof( RBTree ) );
x = y->lchild;
y->lchild = x->rchild;
if ( x->rchild != rbtree->lchild ){
x->rchild->parent = y;
}
x->parent = y->parent;
if ( y->parent == rbtree->lchild ){
rbtree->rchild = x;
}
else if ( y == y->parent->lchild ){
y->parent->lchild = x;
}
else{
y->parent->rchild = x;
}
x->rchild = y;
y->parent = x;
}
void rbInsert( RBTree *rbtree, int value )
{
RBTree *rbnewtree = ( RBTree * )malloc( sizeof( RBTree ) );
rbnewtree->color = 0;
rbnewtree->data = value;
rbnewtree->lchild = rbnewtree->rchild = rbnewtree->parent = rbtree->lchild;
if ( NULL == rbtree->rchild ){
rbnewtree->color = 1;
rbtree->rchild = rbnewtree;
}
else{
RBTree *rbprevtree = ( RBTree * )malloc( sizeof( RBTree ) );
RBTree *root = ( RBTree * )malloc( sizeof( RBTree ) );
root = rbtree;
rbtree = rbtree->rchild;
rbprevtree = rbtree;
while ( root->lchild != rbtree ){
rbprevtree = rbtree;
if ( value < rbtree->data ){
rbtree = rbtree->lchild;
}
else{
rbtree = rbtree->rchild;
}
}
rbnewtree->parent = rbprevtree;
if ( rbnewtree->data < rbprevtree->data ){
rbprevtree->lchild = rbnewtree;
}
else{
rbprevtree->rchild = rbnewtree;
}
rbInsertFixup( root, rbnewtree );
}
}
void rbInsertFixup( RBTree *rbtree, RBTree *z )
{
while ( 0 == z->parent->color ){
if ( z->parent == z->parent->parent->lchild ){
RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
y = z->parent->parent->rchild;
if ( 0 == y->color ){
z->parent->color = 1;
y->color = 1;
z->parent->parent->color = 0;
z = z->parent->parent;
}
else if ( z == z->parent->rchild ){
z = z->parent;
leftRotate( rbtree, z );
}
else{
z->parent->color = 1;
z->parent->parent->color = 0;
rightRotate( rbtree, z->parent->parent );
}
}
else{
RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
y = z->parent->parent->lchild;
if ( 0 == y->color ){
z->parent->color = 1;
y->color = 1;
z->parent->parent->color = 0;
z = z->parent->parent;
}
else if ( z == z->parent->rchild ){
z = z->parent;
leftRotate( rbtree, z );
}
else{
z->parent->color = 1;
z->parent->parent->color = 0;
rightRotate( rbtree, z->parent->parent );
}
}
}
rbtree->rchild->color = 1;
}
int rbDelete( RBTree *rbtree, int value )
{
int yOriginalColor;
RBTree *x = ( RBTree * )malloc( sizeof( RBTree ) );
RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
RBTree *z = ( RBTree * )malloc( sizeof( RBTree ) );
z = rbSearch( rbtree, rbtree, value );
if ( z == rbtree->lchild ){
return 0;
}
y = z;
yOriginalColor = y->color;
if ( z->lchild == rbtree->lchild ){
x = z->rchild;
rbTransplant( rbtree, z, z->rchild );
}
else if ( z->rchild == rbtree->lchild ){
x = z->lchild;
rbTransplant( rbtree, z, z->lchild );
}
else{
y = rbtreeSuccessor( rbtree, z );
yOriginalColor = y->color;
x = y->rchild;
if ( y->parent == z ){
x->parent = y;
}
else{
rbTransplant( rbtree, y, y->rchild );
y->rchild = z->rchild;
y->rchild->parent = y;
}
rbTransplant( rbtree, z, y );
y->lchild = z->lchild;
y->lchild->parent = y;
y->color = z->color;
}
if ( 1 == yOriginalColor ){
rbDeleteFixup( rbtree, x );
}
return 1;
}
void rbTransplant( RBTree *rbtree, RBTree *u, RBTree *v )
{
if ( u->parent == rbtree->lchild ){
rbtree->rchild = v;
}
else if ( u == u->parent->lchild ){
u->parent->lchild = v;
}
else{
u->parent->rchild = v;
}
v->parent = u->parent;
}
RBTree *rbtreeMinimum( RBTree *root, RBTree *rbtree )
{
while ( root->lchild != rbtree->lchild ){
rbtree = rbtree->lchild;
}
return rbtree;
}
RBTree *rbtreeMaximum( RBTree *root, RBTree *rbtree )
{
while ( root->lchild != rbtree->rchild ){
rbtree = rbtree->rchild;
}
return rbtree;
}
RBTree *rbtreeSuccessor( RBTree *rbtree, RBTree *x )
{
RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
if ( rbtree->lchild != x->rchild ){
return rbtreeMinimum( rbtree, x->rchild );
}
y = x->parent;
while ( rbtree->lchild != y && x == y->rchild ){
x = y;
y = y->parent;
}
return y;
}
RBTree *rbSearch( RBTree *root, RBTree *rbtree, int value )
{
if ( root->lchild == rbtree || rbtree->data == value ){
return rbtree;
}
if ( value < rbtree->data ){
return rbSearch( root, rbtree->lchild, value );
}
else{
return rbSearch( root, rbtree->rchild, value );
}
}
void rbShowTree( RBTree *rbtree )
{
if ( rbtree->data != INT_MIN ){
rbShowTree( rbtree->lchild );
printf("{%d:%s} ", rbtree->data, rbtree->color ? "BLACK" : "RED" );
rbShowTree( rbtree->rchild );
}
}
void rbDeleteFixup( RBTree *rbtree, RBTree *x )
{
while ( rbtree->lchild != x && x->color == 1 ){
RBTree *w = ( RBTree * )malloc( sizeof( RBTree ) );
if ( x == x->parent->lchild ){
w = x->parent->rchild;
if ( 0 == w->color ){
w->color = 1;
x->parent->color = 0;
leftRotate( rbtree, x->parent );
w = x->parent->rchild;
}
if ( 1 == w->lchild->color && 1 == w->rchild->color ){
w->color = 0;
x = x->parent;
}
else if ( 1 == w->rchild->color ){
w->lchild->color = 1;
w->color = 0;
rightRotate( rbtree, w );
w = x->parent->rchild;
}
else{
w->color = x->parent->color;
x->parent->color = 1;
w->rchild->color = 1;
leftRotate( rbtree, x->parent );
x = rbtree->lchild;
}
}
else{
//我不能保证下面这个代码块是正确的,但是不知道如何举出测试的例子!!!
w = x->parent->lchild;
if ( 0 == w->color ){
w->color = 1;
x->parent->color = 0;
rightRotate( rbtree, x->parent );
w = x->parent->lchild;
}
if ( 1 == w->lchild->color && 1 == w->rchild->color ){
w->color = 0;
x = x->parent;
}
else if ( 1 == w->rchild->color ){
w->lchild->color = 1;
w->color = 0;
leftRotate( rbtree, w );
w = x->parent->rchild;
}
else{
w->color = x->parent->color;
x->parent->color = 1;
w->rchild->color = 1;
rightRotate( rbtree, x->parent );
x = rbtree->lchild;
}
}
}
x->color = 1;
}