红黑树实现

/*
* RED-BLACK-TREE
*
*/

#include
<cstdio>
using namespace std;

const int MAXN = 10000;
const int RED = 0, BLACK = 1, ROOT = 0;
struct SData{
int key, color;
SData
*left, *right, *p;
};

SData
*rbtree[MAXN];
SData
*nil = new SData;

void ini(){
nil
->color = BLACK;
rbtree[ROOT]
= nil;
}

SData
*rb_minimum(SData *r){
while(r->left != nil)
r
= r->left;
return r;
}


SData
*rb_successor(SData *x){
if(x->right != nil)
return rb_minimum(x->right);
else{
while(x == x->p->right)
x
= x->p;
return x->p;
}
}


void left_rotate(SData *x){
SData
*y = x->right;
x
->right = y->left;
if(y->left != nil) y->left->p = x;
y
->p = x->p;
if(x->p == nil) //树根!!!(重要)(若直接x->p = y 则x为树跟时会出错)
rbtree[ROOT] = y;
else if(x->p->left == x)
x
->p->left = y;
else
x
->p->right = y;

x
->p = y;
y
->left = x;
}

void right_rotate(SData *x){
SData
*y = x->left;
x
->left = y->right;
if(y->right != nil) y->right->p = x;
y
->p = x->p;
if(x->p == nil)
rbtree[ROOT]
= y;
else if(x->p->left == x)
x
->p->left = y;
else
x
->p->right = y;

x
->p = y;
y
->right = x;
}


void rb_insert_fixup(SData *z){
while(z->p->color == RED){
if(z->p == z->p->p->left){
SData
*y = z->p->p->right;
//case 1
if(y->color == RED){
z
->p->color = y->color = BLACK;
z
->p->p->color = RED;
z
= z->p->p;
}
else{
//case 2
if(z == z->p->right){
z
= z->p;
left_rotate(z);
}
//case 3
z->p->color = BLACK;
z
->p->p->color = RED;
right_rotate(z
->p->p);
}
}
else{
SData
*y = z->p->p->left;
//case 1
if(y->color == RED){
z
->p->color = y->color = BLACK;
z
->p->p->color = RED;
z
= z->p->p;
}
else{
//case 2
if(z == z->p->left){
z
= z->p;
right_rotate(z);
}
//case 3
z->p->color = BLACK;
z
->p->p->color = RED;
left_rotate(z
->p->p);
}
}
}
rbtree[ROOT]
->color = BLACK;
}

SData
* rb_insert(SData *z){
SData
*y = nil;
SData
*x = rbtree[ROOT];
while(x != nil){
y
= x;
if(z->key > x->key)
x
= x->right;
else
x
= x->left;
}

if(y == nil){
rbtree[ROOT]
= z; rbtree[ROOT]->p = nil;
}
else if(z->key > y->key){
y
->right = z; z->p = y;
}
else{
y
->left = z; z->p = y;
}

z
->color = RED;
z
->left = z->right = nil;

rb_insert_fixup(z);
return z;
}


void rb_delete_fixup(SData *z){
while(z->color == BLACK && z != rbtree[ROOT]){
if(z->p->left == z){
SData
*w = z->p->right;
//case 1
if(w->color == RED){
w
->color = BLACK;
z
->p->color = RED;
z
= z->p;
left_rotate(z);
w
= z->p->right;
}

//case 2
if(w->left->color == BLACK && w->right->color == BLACK){
w
->color = RED;
z
= z->p;
}
//case 3
else if(w->right->color == BLACK){
w
->left->color = BLACK;
w
->color = RED;
right_rotate(w);
w
= z->p->right;
}
//case 4
w->right->color = BLACK;
w
->color = z->p->color;
z
->p->color = BLACK;
left_rotate(z
->p);
z
= rbtree[ROOT]; //case3之后可以退出循环了。。 保持root的颜色为black
}
else{
SData
*w = z->p->left;
//case 1
if(w->color == RED){
w
->color = BLACK;
z
->p->color = RED;
z
= z->p;
right_rotate(z);
w
= z->p->left;
}

//case 2
if(w->left->color == BLACK && w->right->color == BLACK){
w
->color = RED;
z
= z->p;
}
//case 3
else if(w->left->color == BLACK){
w
->right->color = BLACK;
w
->color = RED;
left_rotate(w);
w
= z->p->left;
}
//case 4
w->left->color = BLACK;
w
->color = z->p->color;
z
->p->color = BLACK;
right_rotate(z
->p);
z
= rbtree[ROOT]; //case3之后可以退出循环了。。 保持root的颜色为black
}
}
z
->color = BLACK;
}

SData
* rb_delete(SData *z){
SData
*y;
if(z->left != nil || z->right->right != nil)
y
= z;
else
y
= rb_successor(z);

SData
*x;
if(y->left != nil) x = y->left;
else x = y->right;

x
->p = y->p;
if(y->p == nil) rbtree[ROOT] = x;
else{
if(y->p->left == y) y->p->left = x;
else y->p->right = x;
}
//删除的是z的后继
if(y != z){
y
->p = z->p;
y
->left = z->left; y->right = z->right;
}

if(y->color == BLACK)
rb_delete_fixup(y);

return y;
}

void rb_inorder_walk(SData *r){
if(r == nil) return;
rb_inorder_walk(r
->left);
printf(
"%d\n", r->key);
rb_inorder_walk(r
->right);
}



int main(){
ini();
int tmp_key;
while(scanf("%d", &tmp_key) == 1){
SData
*tmp = new SData; //注意在里面新建对象。。因为tmp是指针!
tmp->key = tmp_key;
rb_insert(tmp);
}

rb_inorder_walk(rbtree[ROOT]);

return 0;
}

posted on 2011-07-21 21:37  龙豆  阅读(519)  评论(0编辑  收藏  举报

导航