Introduction to Algorithms Chapter 13: Red Black Tree

//

//  main.cpp

//  Data Structure TRY1

//

//  Created by zr9558 on 6/7/13.

//  Copyright (c) 2013 zr9558. All rights reserved.

//



// Introduction to Algorithms: Chapter 13 Red Black Tree



#include<iostream>

using namespace std;

#include<math.h>



template<typename Comparable>

class RedBlackTree

{

public:

    RedBlackTree()

    {

        NIL=new RBNode();

        NIL->parent=NIL->left=NIL->right=NIL;

        

        root=NIL;

    }

    

    RedBlackTree( const RedBlackTree &rhs)

    {

        NIL=new RBNode();

        NIL->parent=NIL->left=NIL->right=NIL;

        

        root=clone(rhs.root);

    }

    

    const RedBlackTree & operator= ( const RedBlackTree &rhs)

    {

        if( this!=&rhs)

        {

            makeEmpty(root);

            delete NIL;

            

            NIL=new RBNode();

            NIL->parent=NIL->left=NIL->right=NIL;

            

            root=clone(rhs.root);

        }

        return *this;

    }

    

    ~ RedBlackTree()

    {

        makeEmpty(root);

        delete NIL;

    }

    

    bool contain( const Comparable &x) const

    {

        RBNode *temp=Tree_Search(root, x);

        if( temp==NIL) return false;

        else return true;

    }

    

    const Comparable & findMin() const

    {

        return Tree_Minimum(root)->key;

    }

    

    const Comparable & findMax() const

    {

        return Tree_Maximum(root)->key;

    }

    

    bool isEmpty() const

    {

        return root==NIL;

    }

    

    void insert( const Comparable &k)

    {

        RBNode *t=new RBNode(k);

        RB_Insert(t);

    }

    

    void remove( const Comparable &k)

    {

        RBNode * t=Tree_Search(root, k);

        if( t!=NIL)

        {

            RBNode * y=RB_Delete(t);

            delete y;

        }

    }

    

    void print()

    {

        Print(root,0);

    }

    

    void printInOrder()

    {

        PrintInOrder(root);

        cout<<endl;

    }

    

    

    enum {RED, BLACK};

    

private:

    struct RBNode

    {

        Comparable key;

        RBNode *left, *right, *parent;

        int color;

        

        RBNode( const Comparable &theElement=Comparable(), RBNode *lt=NULL, RBNode *rt=NULL,

               RBNode *pt=NULL, int c=BLACK): key(theElement), left(lt), right(rt), parent(pt), color(c){}

        

    };

    

    RBNode *root;

    RBNode *NIL;

    

    //assume x->right!=NIL and root->parent==NIL;

    void Left_Rotate( RBNode *x)

    {

        RBNode *y=x->right;    // set y

        x->right=y->left;      // Turn y's left subtree into x's right subtree

        

        if( y->left!=NIL) y->left->parent=x;

        

        y->parent=x->parent;   // Link x's parent to y

        if( x->parent==NIL)

            root=y;

        else if( x==x->parent->left)

            x->parent->left=y;

        else x->parent->right=y;

        

        y->left=x;

        x->parent=y;

    }

    

    //assume x->left!=NIL and root->parent==NIL

    void Right_Rotate( RBNode *x)

    {

        RBNode *y=x->left;

        x->left=y->right;

        

        if( y->right!=NIL)

            y->right->parent=x;

        

        y->parent=x->parent;

        if( x->parent==NIL)

            root=y;

        else if( x==x->parent->left)

            x->parent->left=y;

        else x->parent->right=y;

        

        y->right=x;

        x->parent=y;

    }

    

    void RB_Insert_Fixup( RBNode *z)

    {

        while( z->parent->color==RED)

        {

            if( z->parent==z->parent->parent->left)

            {

                RBNode *y=z->parent->parent->right;

                

                if( y->color==RED// case 1

                {

                    z->parent->color=BLACK;

                    y->color=BLACK;

                    z->parent->parent->color=RED;

                    z=z->parent->parent;

                }

                else

                {

                    if( z==z->parent->right// case 2

                    {

                        z=z->parent;

                        Left_Rotate(z);

                    }

                                              // case 3; case 2 will change to case 3

                    z->parent->color=BLACK;

                    z->parent->parent->color=RED;

                    Right_Rotate(z->parent->parent);

                }

            }

            else

            {

                RBNode *y=z->parent->parent->left;

                

                if( y->color==RED// case 1

                {

                    z->parent->color=BLACK;

                    y->color=BLACK;

                    z->parent->parent->color=RED;

                    z=z->parent->parent;

                }

                else

                {

                    if( z==z->parent->left// case 2

                    {

                        z=z->parent;

                        Right_Rotate(z);

                    }

                                             // case 3; case 2 will change to case 3

                    z->parent->color=BLACK;

                    z->parent->parent->color=RED;

                    Left_Rotate(z->parent->parent);

                }

            }

        }

        root->color=BLACK;

    }

    

    

    

    void RB_Insert( RBNode *z)

    {

        RBNode *y=NIL;

        RBNode *x=root;

        

        while( x!=NIL)

        {

            y=x;

            if( z->key<x->key)

                x=x->left;

            else x=x->right;

        }

        

        z->parent=y;

        

        if( y==NIL)

            root=z;

        else if( z->key < y->key)

            y->left=z;

        else y->right=z;

        

        z->left=NIL;

        z->right=NIL;

        z->color=RED;

        RB_Insert_Fixup(z);

    }

    

    RBNode *Tree_Minimum( RBNode *x) const

    {

        while( x->left!=NIL)

            x=x->left;

        return x;

    }

    

    RBNode *Tree_Maximum( RBNode *x) const

    {

        while( x->right!=NIL)

            x=x->right;

        return x;

    }

    

    RBNode *Tree_Successor( RBNode *x)

    {

        if( x->right!=NIL)

            return Tree_Minimum(x->right);

        

        RBNode *y=x->parent;

        while( y!=NIL && x==y->right)

        {

            x=y;

            y=y->parent;

        }

        return y;

    }

    

    RBNode *Tree_Search( RBNode *x, const Comparable &k) const

    {

        if( x==NIL || k==x->key)

            return x;

        

        if( k<x->key)

            return Tree_Search(x->left, k);

        else return Tree_Search(x->right, k);

    }

    

    void RB_Delete_Fixup( RBNode *x)

    {

        while( x!=root && x->color==BLACK)

        {

            if( x==x->parent->left)

            {

                RBNode *w=x->parent->right;

                

                if( w->color==RED// case 1

                {

                    w->color=BLACK;

                    x->parent->color=RED;

                    Left_Rotate(x->parent);

                    w=x->parent->right;

                }

                

                if( w->left->color==BLACK && w->right->color==BLACK) // case 2

                {

                    w->color=RED;

                    x=x->parent;

                }

                else

                {

                    if( w->right->color==BLACK// case 3

                    {

                        w->left->color=BLACK;

                        w->color=RED;

                        Right_Rotate(w);

                        w=x->parent->right;

                    }

                    

                    w->color=x->parent->color;

                    x->parent->color=BLACK;

                    w->right->color=BLACK;

                    Left_Rotate(x->parent);

                    x=root;

                }

            }

            else 

            {

                RBNode *w=x->parent->left;

                

                if( w->color==RED// case 1

                {

                    w->color=BLACK;

                    x->parent->color=RED;

                    Right_Rotate(x->parent);

                    w=x->parent->left;

                }

                

                if( w->right->color==BLACK && w->left->color==BLACK) // case 2

                {

                    w->color=RED;

                    x=x->parent;

                }

                else

                {

                    if( w->left->color==BLACK// case 3

                    {

                        w->right->color=BLACK;

                        w->color=RED;

                        Left_Rotate(w);

                        w=x->parent->left;

                    }

                    

                    w->color=x->parent->color;

                    x->parent->color=BLACK;

                    w->left->color=BLACK;

                    Right_Rotate(x->parent);

                    x=root;

                }

            }

        }

        x->color=BLACK;

    }

    

    

    RBNode * RB_Delete( RBNode *z)

    {

        RBNode *y=NULL;

        if( z->left==NIL || z->right==NIL)

            y=z;

        else y=Tree_Successor(z);

        

        RBNode *x=NULL;

        if( y->left!=NIL)

            x=y->left;

        else x=y->right;

        

        x->parent=y->parent;

        if( y->parent==NIL)

            root=x;

        else if( y==y->parent->left)

            y->parent->left=x;

        else y->parent->right=x;

        

        if(y!=z)

            z->key=y->key;

        

        if( y->color==BLACK)

            RB_Delete_Fixup(x);

        

        return y;

    }

    

    RBNode *clone( RBNode *t) const

    {

        if( t->left==t || t->right==t) // t==NIL

            return NIL;

        else return new RBNode(t->key, clone(t->left), clone(t->right), t->parent, t->color);

    }

    

    void Print( RBNode *t, int level)

    {

        if( t!=t->left) // t!=NIL

        {

            Print(t->right,level+1);

            for( int i=0; i<4*level; ++i)

                cout<<" ";

            

            cout<<t->key<<" "<<t->color<<endl;

            Print(t->left, level+1);

        }

    }

    

    void PrintInOrder( RBNode *t)

    {

        if( t!=t->left)

        {

            PrintInOrder(t->left);

            cout<<t->key<<" ";

            PrintInOrder(t->right);

        }

    }

    

    void makeEmpty( RBNode *t)

    {

        if( t!=t->left)

        {

            makeEmpty(t->left);

            makeEmpty(t->right);

            delete t;

        }

    }

    

    

};






int main()

{

    RedBlackTree<int> T;

    

    for( int i=0; i<20; ++i)

        T.insert(i);


    

    

    T.print();

    T.printInOrder();

    

    int x;

    while( cin>>x)

    {

        T.remove(x);

        T.print();

        T.printInOrder();

    }

    

    T.print();

    

    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值