第13章 红黑树代码

红黑树本质是二叉搜索树,只是它有如下的额外条件

  • 每个结点要么为红色要么为黑色;
  • 根节点是黑色的 ;
  • NULL结点是黑色的;
  • 如果一个结点是红色的,那么它的两个子节点都是黑色的;
  • 对每个结点,从该结点到其所有后代叶节点的简单路径上,均包含相同数目的黑色结点。

之所以要有如下的额外条件,是为了保证树高为O(lgn)。因为在普通二叉搜索树中,树高为O(n),而不是O(lgn)。

下面给出了结点左旋结点右旋, 和修复插入所带来的性质破坏修复删除所带来的性质破坏以及插入代码 和删除代码,其它操作,如查找,遍历,后继和前驱都和普通二叉搜索树一样。

首先,还是要定义结点存储的元素类型,定义如下:
enum {RED,BLACK}

template<class Type>
struct node{
 12                 Type element;
 13                 node* parent;
 14                 node* left;
 15                 node* right;
 16                 int color;
 17                 node(const Type& e=Type(),node* p=0,node* l=0,node* r=0,int c=BLACK):element(e),parent(p),left(l),right(r),color(c){}
 18         };
结点左旋:
template<class Type>
void redBlackTree<Type>::leftRotate(node* x)
{
        if(x->right==nullNode)
                throw runtime_error("the node can't be imposed on the operation of leftRotate");

        node* y=x->right;

        // the parent of node y is assigned by the parent of node x
        y->parent=x->parent;
        if(x->parent==nullNode)
                root=y;
        else if(x==x->parent->left)
                x->parent->left=y;
        else
                x->parent->right=y;

        // the right of node x is assigned by the left of node y
        x->right=y->left;
        if(y->left!=nullNode)
                y->left->parent=x;

        //the left of node y is assigned by node x
        y->left=x;
        x->parent=y;
}
结点右旋
template<class Type>
void redBlackTree<Type>::rightRotate(node* x)
{
        if(x->left==nullNode)
                throw runtime_error("the node can't be imposed on the operation of rightRotate");

        node* y=x->left;

        // the parent of node y is assigned by the parent of node x
        y->parent=x->parent;
        if(x->parent==nullNode)
                root=y;
        else if(x==x->parent->left)
                x->parent->left=y;
        else
                x->parent->right=y;

        //the left of node x is assigned by the right of node y
        x->left=y->right;
        if(y->right!=nullNode)
                y->right->parent=x;

        //the right of node y is assigned by node x
        y->right=x;
        x->parent=y;
}
修复插入所带来的性质破坏:
template<class Type>
void redBlackTree<Type>::RBInsertFixup(node* currentNode)
{
        while(currentNode->parent->color==RED){
                if(currentNode->parent==currentNode->parent->parent->left){
                        node* uncleNode=currentNode->parent->parent->right;
                        // 书本中的插入情况1
                        if(uncleNode->color==RED){
                                currentNode->parent->color=BLACK;
                                uncleNode->color=BLACK;
                                currentNode->parent->parent->color=RED;
                                currentNode=currentNode->parent->parent;
                        }
                        //书本中的插入情况2
                        else if(currentNode==currentNode->parent->right){
                                currentNode=currentNode->parent;
                                leftRotate(currentNode);
                        }
                        //书本中的插入情况3
                        else{
                                currentNode->parent->color=BLACK;
                                currentNode->parent->parent->color=RED;
                                rightRotate(currentNode->parent->parent);
                        }
                }

                //与与之匹配的if的情况对称,left换成right,right换成left即可
                else {
                        node* uncleNode=currentNode->parent->parent->left;
                        if(uncleNode->color==RED){
                                currentNode->parent->color=BLACK;
                                uncleNode->color=BLACK;
                                currentNode->parent->parent->color=RED;
                                currentNode=currentNode->parent->parent;
                        }
                        else if(currentNode==currentNode->parent->left){
                                currentNode=currentNode->parent;
                                rightRotate(currentNode);
                        }
                        else{
                                currentNode->parent->color=BLACK;
                                currentNode->parent->parent->color=RED;
                                leftRotate(currentNode->parent->parent);
                        }
                }
        }

        root->color=BLACK;
}
插入:
template<class Type>
bool redBlackTree<Type>::insert(const Type& val)
{
        node* parentNode=nullNode;
        node* currentNode=root;

         //找到要插入的位置;
        while(currentNode!=nullNode){
                parentNode=currentNode;
                if(currentNode->element<val)
                        currentNode=currentNode->right;
                else if(val<currentNode->element)
                        currentNode=currentNode->left;
                else
                        return false;
        }

        // 插入该元素并且修复该元素所带来红黑树性质的破坏;
        if(parentNode==nullNode)
                root=new node(val,nullNode,nullNode,nullNode,BLACK);
        else if(val<parentNode->element){
                parentNode->left=new node(val,parentNode,nullNode,nullNode,RED);
                RBInsertFixup(parentNode->left);
        }
        else{
                parentNode->right=new node(val,parentNode,nullNode,nullNode,RED);
                RBInsertFixup(parentNode->right);
        }

        return true;
}
修复删除所带来的性质破坏
template<class Type>
void redBlackTree<Type>::RBRemoveFixup(node* currentNode)
{
        while(currentNode!=root&&currentNode->color==BLACK){
                if(currentNode==currentNode->parent->left){
                        node* uncleNode=currentNode->parent->right;
                        //书本中的删除情况1
                        if(uncleNode->color==RED){
                                uncleNode->color=BLACK;
                                currentNode->parent->color=RED;
                                leftRotate(currentNode->parent);
                        }
                        //书本中的删除情况2
                        else if(uncleNode->left->color==BLACK&&uncleNode->right->color==BLACK){
                                uncleNode->color=RED;
                                currentNode=currentNode->parent;
                        }
                        //书本中的删除情况3
                        else if(uncleNode->right->color==BLACK){
                                uncleNode->color=RED;
                                uncleNode->left->color=BLACK;
                                rightRotate(uncleNode);
                        }
                        //书本中的删除清况4
                        else{
                                uncleNode->color=currentNode->parent->color;
                                uncleNode->right->color=BLACK;
                                currentNode->parent->color=BLACK;
                                leftRotate(currentNode->parent);
                                currentNode=root;
                        }
                }
            //与与之匹配的if的情况对称,left与right互换即可。
                else{
                        node* uncleNode=currentNode->parent->left;

                        if(uncleNode->color==RED){
                                uncleNode->color=BLACK;
                                currentNode->parent->color=RED;
                                rightRotate(currentNode->parent);
                        }
                        else if(uncleNode->right->color==BLACK&&uncleNode->left->color==BLACK){
                                uncleNode->color=RED;
                                currentNode=currentNode->parent;
                        }
                        else if(uncleNode->left->color==BLACK){
                                uncleNode->color=RED;
                                uncleNode->right->color=BLACK;
                                leftRotate(uncleNode);
                        }
                        else{
                                uncleNode->color=currentNode->parent->color;
                                uncleNode->left->color=BLACK;
                                currentNode->parent->color=BLACK;
                                rightRotate(currentNode->parent);
                                currentNode=root;
                        }
                }
        }

        currentNode->color=BLACK;
}
删除:
template<class Type>
void redBlackTree<Type>::transplant(node* u,node* v) // node v is to replace node u;
{
        if(u->parent==nullNode)
                root=v;
        else if(u==u->parent->left)
                u->parent->left=v;
        else
                u->parent->right=v;

        v->parent=u->parent;
}

template<class Type>
bool redBlackTree<Type>::remove(const Type& val)
{
        node* searchNode=search(val,root);//找到要删除的结点
        if(searchNode==nullNode)
                return false;//要删除的值不存在

        node* tmpNode=searchNode;
        int tmpNodeOriginalColor=tmpNode->color;
        node* nextOfTmpNode=0;

        //要删除的结点左边为空
        if(searchNode->left==nullNode){
                nextOfTmpNode=tmpNode->right;
                transplant(searchNode,searchNode->right);
        }
        //要删除的结点右边为空
        else if(searchNode->right==nullNode){
                nextOfTmpNode=tmpNode->left;
                transplant(searchNode,searchNode->left);
        }
        //要删除的结点左右均不为空
        else{
                tmpNode=findMin(searchNode->right);//找到要删除结点的后继结点。
                nextOfTmpNode=tmpNode->right;

                //用要被删除结点的后继结点取替换它
                if(tmpNode->parent==searchNode)
                        nextOfTmpNode->parent=tmpNode;
                else{
                        transplant(tmpNode,tmpNode->right);
                        tmpNode->right=searchNode->right;
                        tmpNode->right->parent=tmpNode;
                }
                transplant(searchNode,tmpNode);
                tmpNode->left=searchNode->left;
                tmpNode->color=searchNode->color;

        }

    //删除结点并且修复删除所带来的红黑树性质的破坏
        delete searchNode;
        if(tmpNodeOriginalColor==BLACK)
                RBRemoveFixup(nextOfTmpNode);

        return false;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值