红黑树实现 实现代码

/*
 * 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值