zoukankan      html  css  js  c++  java
  • 红黑树实现

    /*
    * 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;
    }
  • 相关阅读:
    作业1
    113
    112
    工作量统计
    测试大纲
    2019-2020-2 20175335丹增罗布《网络对抗技术》Exp8 Web基础
    2019-2020-2 20175335丹增罗布 《网络对抗技术》Exp7 网络欺诈防范
    2019-2020-2 20175335丹增罗布 《网络对抗技术》Exp6 MSF基础应用
    2019-2020-2 20175335 丹增罗布 《网络对抗技术》Exp5 信息搜集与漏洞扫描
    2019-2020-2 20175335 丹增罗布《网络对抗技术》Exp4 恶意代码分析
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2113280.html
Copyright © 2011-2022 走看看