红黑树的c++实现

//

//  main.cpp

//  RBTree

//

//  Created by 孟文斌 on 15/4/22.

//  Copyright (c) 2015 孟文斌. All rights reserved.

//


#include <iostream>

#include <stack>

#include <queue>

#include <time.h>


using namespace std;


const int COLOR_RED = 0;

const int COLOR_BLACK = 1;


struct TreeNode{

    int key;

    int color;//0red 1black

    TreeNode* p;

    TreeNode *left;

    TreeNode *right;

    TreeNode(int x,int c,TreeNode *init):key(x),color(c),p(init),left(init),right(init){}

    TreeNode(int x,int c):key(x),color(c),p(NULL),left(NULL),right(NULL){}

};


TreeNode * const nill = new TreeNode(-1,COLOR_BLACK);


class RBTree{

private:

    TreeNode * root;

    //when val is not the minmun of the Tree find the Node which key is min less than the val

    //when val is the minmun of the Tree find the Node which key is min larger than the val

    TreeNode* findPos(int val){

        TreeNode* t = root;

        TreeNode *pre = root;

        while(t != nill){

            if(t->key == val) return t;

            pre = t;

            if(t->key < val) t = t->right;

            else t = t->left;

        }

        return pre;

    }

    

    void RB_left_rotate(TreeNode* t){//t call left rotation operation

        if(t == NULL || t == nill) return;

        TreeNode* p = t->p,*s = t->right;

        if(s == nill) return;

        t->right = s->left;

        if(s->left != nill)  s->left->p = t;

        s->left = t;

        t->p = s;

        if(p != nill){

            if(p->left == t) p->left = s;

            else p->right = s;

        }else{

            root = s;

        }

        s->p = p;

    }

    

    void RB_right_rotate(TreeNode* t){//t call right rotation operation

        if(t == NULL || t == nill) return;

        TreeNode* p = t->p,*s = t->left;

        if(s == nill) return;

        t->left = s->right;

        if(s->right != nill) s->right->p = t;

        s->right = t;

        t->p = s;

        

        if(p != nill){

            if(p->left == t) p->left = s;

            else p->right = s;

        }else{

            root = s;

        }

        s->p = p;

    }

    

    void RB_insert_fixup(TreeNode* t){

        if(t == nill || t->p == root) return;

        while(t->p->color == COLOR_RED){

            if(t->p == t->p->p->left){//t's father is in left tree

                // t's father and uncle are both red: change father and uncle into black and t's grandfather into red

                if(t->p->p->right->color == COLOR_RED){

                    t->p->color = COLOR_BLACK;

                    t->p->p->right->color = COLOR_BLACK;

                    t->p->p->color = COLOR_RED;

                    t = t->p->p;

                }else{

                    if(t == t->p->right) {//uncle is black and t is the right child

                        t = t->p;

                        RB_left_rotate(t);

                    }

                    t->p->color = COLOR_BLACK;//uncle is black and t is the left child

                    t->p->p->color = COLOR_RED;

                    RB_right_rotate(t->p->p);

                }

            }else {//exchange the direction

                if(t->p->p->left->color == COLOR_RED){

                    t->p->color = COLOR_BLACK;

                    t->p->p->left->color = COLOR_BLACK;

                    t->p->p->color = COLOR_RED;

                    t = t->p->p;

                }else{

                    if(t == t->p->left) {

                        t = t->p;

                        RB_right_rotate(t);

                    }

                    t->p->color = COLOR_BLACK;

                    t->p->p->color = COLOR_RED;

                    RB_left_rotate(t->p->p);

                }

            }

        }

        root->color = COLOR_BLACK;

    }

    

    void RB_delete_fixup(TreeNode* t){

        if(t == NULL) return;

        TreeNode* w = NULL;

        while(t != root && t->color == COLOR_BLACK){

            if(t == t->p->left){//t is left child

                w = t->p->right;

                if(w->color == COLOR_RED){//brother is red

                    w->color = COLOR_BLACK;

                    t->p->color = COLOR_RED;

                    RB_left_rotate(t->p);

                    w = t->p->right;

                }

                if(w->left->color==COLOR_BLACK && w->right->color==COLOR_BLACK){

                    //brother is black and his children are also black

                    w->color = COLOR_RED;

                    t = t->p;

                }else {

                    if(w->right->color == COLOR_BLACK){//left child is black and right child is red

                        w->left->color = COLOR_BLACK;

                        w->color = COLOR_RED;

                        RB_right_rotate(w);

                        w = t->p->right;

                    }

                    w->color = t->p->color;//right child is red

                    t->p->color = COLOR_BLACK;

                    w->right->color = COLOR_BLACK;

                    RB_left_rotate(t->p);

                    t = root;

                }

            }else{//exchanged all direction

                w = t->p->left;

                if(w->color == COLOR_RED){//brother is red

                    w->color = COLOR_BLACK;

                    t->p->color = COLOR_RED;

                    RB_right_rotate(t->p);

                    w = t->p->left;

                }

                if(w->left->color==COLOR_BLACK && w->right->color==COLOR_BLACK){//brother is black and his children are also black

                    w->color = COLOR_RED;

                    t = t->p;

                }else {

                    if(w->left->color == COLOR_BLACK){//left child is black and right child is red

                        w->right->color = COLOR_BLACK;

                        cout<<endl;

                        w->color = COLOR_RED;

                        RB_left_rotate(w);

                        cout<<endl;

                        w = t->p->left;

                    }

                    w->color = t->p->color;//right child is red

                    w->left->color = COLOR_BLACK;

                    t->p->color = COLOR_BLACK;

                    RB_right_rotate(t->p);

                    t = root;

                }

            }

        }

        t->color = COLOR_BLACK;

    }

    

    /**

     * insert a Node into the Tree

     */

    void insertTreeNode(TreeNode* t){

        TreeNode * pre = findPos(t->key);//find the pos to insert

        if(pre->key == t->key) return;

        if(pre->key < t->key) pre->right = t;

        else pre->left = t;

        t->p = pre;

        RB_insert_fixup(t);// fix the tree

    }

    

    /**

     * delete a Node from the Tree

     */

    void deleteTreeNode(TreeNode* z){

        if(z == NULL || z==nill) {

            return;

        }

        TreeNode *y = NULL,*x = NULL;

        if(z->left==nill || z->right==nill) y = z;//t is single

        else y =  Tree_Successor(z);// t has both right and left child

        if(y->left != nill) x = y->left;//t's left child is not nill point x to s's left

        else x = y->right;

        x->p = y->p; //point x's parent to s's parent

        if(y->p == nill) root = x;

        else if(y->p->left == y) y->p->left = x;

        else y->p->right = x;

        if(y != z) z->key = y->key; // chage the z to y and y is deleted

        if(y->color == COLOR_BLACK) RB_delete_fixup(x);//fix the tree

    }

    TreeNode * Tree_Minimum(TreeNode *x){

        TreeNode *r = x;

        while(r->left != nill)

            r = r->left;

        return r;

    }

    

    TreeNode * Tree_Maximum(TreeNode *x){

        TreeNode *r = x;

        while(r->right != nill)

            r = r->right;

        return r;

    }

    

    TreeNode * Tree_Successor(TreeNode *x){

        if(x->right != nill)

            return Tree_Minimum(x->right);

        TreeNode *y = x->p;

        while(y != nill && x == y->right){

            x = y;

            y = y->p;

        }

        return y;

    }

    

    TreeNode * Tree_Predecesor(TreeNode *x){

        if(x->left != nill)

            return Tree_Maximum(x->left);

        TreeNode *y = x->p;

        while(y != nill && x == y->left){

            x = y;

            y = y->p;

        }

        return y;

    }

public:

    RBTree(int val){

        root = new TreeNode(val,COLOR_BLACK,nill);

    }

    

    RBTree(){

        root = nill;

    }


    

    void insertVals(int *val,int n){

        for(int i=0;i<n;i++){

            insertVal(val[i]);

        }

    }

    

    void clearTree(){

        root = NULL;

        nill->p = NULL;

        //delete other elements garbage collect

    }

    

    void reBuildTree(int *val,int n){

        clearTree();

        for(int i=0;i<n;i++){

            insertVal(val[i]);

        }

    }

    /**

     * insert val into tree

     */

    void insertVal(int val){

        if(root == NULL || root == nill) {

            root = new TreeNode(val,COLOR_BLACK,nill);

            return;

        }

        TreeNode *t = new TreeNode(val,COLOR_RED,nill);

        insertTreeNode(t);

    }

    

    void deleteVal(int val){

        TreeNode *z = findPos(val);

        if(z->key != val) return;// can't find the val

        deleteTreeNode(z);

    }

    

    bool valExit(int val){

        TreeNode * pre = findPos(val);

        if(pre->key == val) return 1;

        return 0;

    }

    

    void inOrderDisplay(){

        if(!root) return;

        stack<TreeNode*> s;

        

        TreeNode* tmp = root;

        int num=0;

        while(tmp!=nill){

            

            s.push(tmp);

            tmp = tmp->left;

        }

        while(!s.empty()){

            tmp = s.top();

            s.pop();

            num++;

            cout<<tmp->key<<" "<<tmp->color<<"  ;";

            tmp = tmp->right;

            while(tmp != nill){

                s.push(tmp);

                tmp = tmp->left;

            }

        }

        cout<<"num:"<<num<<endl;

    }

    

    void layerOrderDisplay(){

        if(!root) return;

        queue<TreeNode*> q1,q2;

        

        TreeNode* tmp = root;

        q1.push(tmp);

        int layer = 0,num=0;

        while(!q1.empty()){

            layer ++;

            while(!q1.empty()){

                tmp = q1.front();

                q1.pop();

                num++;

                cout<<tmp->key<<"->"<<tmp->color<<"->"<<tmp->p->key<<endl;

                if(tmp->left != nill ) q2.push(tmp->left);

                if(tmp->right != nill ) q2.push(tmp->right);

            }

            swap(q1, q2);

        }

        cout<<"layer"<<layer<<" num:"<<num<<endl;

    }

    

    void deleteTest(){

        deleteTreeNode(root->left);

    }

    ~RBTree(){

        delete root;

    }

};

int main(int argc, const char * argv[]) {

    RBTree a;

    srand(time(0));

    for(int k = 1;k<100000;k++){

        srand(k);

        int n = 100;

        int *test = new int[n];

        for(int i=0;i<n;i++){

            test[i] = n*i;//rand();

        }

        a.insertVals(test, n);

        for(int i=0;i<n/5;i++){

            a.deleteVal(test[rand()%n]);

        }

        for(int i=0;i<n;i++){

            test[i] = rand();

        }

        a.insertVals(test, n);

    }

    return 0;

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值