第十四章 数据结构扩张 动态顺序统计部分代码

在这一章中,动态顺序统计和区间树被举例用来显示怎样去扩张一个数据结构。一般来说,扩张一个数据结构分为以下四个步骤:

  • 选择一种基础数据结构;
  • 确定基础数据结构中要维护的附加信息;
  • 检验基础数据结构上的基本修改操作能否维护附加信息;
  • 设计一些新操作。

当然设计一个数据结构的扩张,没有那么顺利,永远包含着试探和纠错。下面给出基于红黑树的动态顺序统计区间树的代码。

动态顺序统计:

下面代码给出了左旋右旋恢复插入引起的红黑树性质的破坏插入恢复删除引起的红黑树性质的破坏删除查找第i小关键字返回一个元素的秩

左旋:
template<class Type>
void orderStatisticTree<Type>::leftRotate(node* x)
{
        node* y=x->right;

        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;

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

        y->left=x;
        x->parent=y;
//上面代码和红黑树右旋代码一样,下面两行代码用来维护附加信息size。
        y->size=x->size;
        x->size=x->left->size+x->right->size+1;
}
右旋:
template<class Type>
void orderStatisticTree<Type>::rightRotate(node* x)
{
         node* y=x->left;

         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;

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

         y->right=x;
         x->parent=y;
//上面代码和红黑树右旋代码一样,下面两行代码用来维护附加信息size。
         y->size=x->size;
         x->size=x->left->size+x->right->size+1;
 }
恢复插入引起的红黑树性质的破坏:

这代码和红黑树那一章的代码一样。

template<class Type>
void orderStatisticTree<Type>::RBInsertFixup(node* currentNode)
{
         while(currentNode->parent->color==RED){
                 if(currentNode->parent==currentNode->parent->parent->left){
                         node* uncleNode=currentNode->parent->parent->right;
                       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->right){
                                 currentNode=currentNode->parent;
                                 leftRotate(currentNode);
                         }
                          else{
                                 currentNode->parent->color=BLACK;
                                 currentNode->parent->parent->color=RED;
                                 rightRotate(currentNode->parent->parent);
                         }
                 }
                 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>
void orderStatisticTree<Type>::insert(const Type& val)
{
        node* currentNode=root;
        node* prevNode=nullNode;

        while(currentNode!=nullNode){
                currentNode->size+=1;//从根到新插入点路径上的各个结点size加1。
                prevNode=currentNode;
                if(val<currentNode->key)
                        currentNode=currentNode->left;
                else
                        currentNode=currentNode->right;
        }

        if(prevNode==nullNode)
                root=new node(val,1,nullNode,nullNode,nullNode,BLACK);
        else if(val<prevNode->key){
                prevNode->left=new node(val,1,prevNode,nullNode,nullNode,RED);
                RBInsertFixup(prevNode->left);
        }
        else{
                prevNode->right=new node(val,1,prevNode,nullNode,nullNode,RED);
                RBInsertFixup(prevNode->right);
        }
}
恢复删除引起的红黑树性质的破坏:
template<class Type>
void orderStatisticTree<Type>::RBRemoveFixup(node* currentNode)
{
        node* tmp=currentNode->parent;
        while(tmp!=nullNode){
                tmp->size=tmp->left->size+tmp->right->size+1;
                tmp=tmp->parent;
        }//将currentNode到根路径上的各个节点size减1。

        while(currentNode!=root&&currentNode->color==BLACK){
                if(currentNode==currentNode->parent->left){
                        node* brotherNode=currentNode->parent->right;
                        if(brotherNode->color==RED){
                                brotherNode->color=BLACK;
                                currentNode->parent->color=RED;
                                leftRotate(currentNode->parent);
                        }
                        else if (brotherNode->left->color==BLACK&&brotherNode->right->color==BLACK){
                                brotherNode->color=RED;
                                currentNode=currentNode->parent;
                        }
                        else if(brotherNode->right->color==BLACK){
                                brotherNode->left->color=RED;
                                brotherNode->color=RED;
                                rightRotate(brotherNode);
                                brotherNode=currentNode->parent->right;
                        }
                        else{
                                brotherNode->color=currentNode->parent->color;
                                currentNode->parent->color=BLACK;
                                leftRotate(currentNode->parent);
                                currentNode=root;
                        }
                }
                else{
                        node* brotherNode=currentNode->parent->left;
                        if(brotherNode->color==RED){
                                brotherNode->color=BLACK;
                                currentNode->parent->color=RED;
                                rightRotate(currentNode->parent);
                        }
                        else if (brotherNode->right->color==BLACK&&brotherNode->left->color==BLACK){
                                brotherNode->color=RED;
                                currentNode=currentNode->parent;
                        }
                        else if(brotherNode->left->color==BLACK){
                                brotherNode->right->color=RED;
                                brotherNode->color=RED;
                                leftRotate(brotherNode);
                                brotherNode=currentNode->parent->left;
                        }
                        else{
                                brotherNode->color=currentNode->parent->color;
                                currentNode->parent->color=BLACK;
                                rightRotate(currentNode->parent);
                                currentNode=root;
                        }
                }
        }

        currentNode->color=BLACK;

}
删除:

代码和红黑树中删除代码一样。

template<class Type>
void orderStatisticTree<Type>::transplant(node* u,node* v)
{
        if(u->parent==nullNode)
                root=v;
        else if(u==u->parent->right)
                u->parent->right=v;
        else
                u->parent->left=v;

        v->parent=u->parent;
}

template<class Type>
bool orderStatisticTree<Type>::remove(const Type& val)
{
        node* searchNode=search(val,root);

        if(searchNode==nullNode)
                return false;

        int originalColor;
        node* x=0;
        if(searchNode->left==nullNode){
                x=searchNode->right;
                transplant(searchNode,searchNode->right);
                originalColor=searchNode->color;
        }
        else if(searchNode->right==nullNode){
                x=searchNode->left;
                transplant(searchNode,searchNode->left);
                originalColor=searchNode->color;
        }
        else{
                node* succNode=findMinimum(searchNode->right);
                originalColor=succNode->color;
                x=succNode->right;

                if(succNode->parent==searchNode)
                        x->parent=succNode;
                else{
                        transplant(succNode,succNode->right);
                        succNode->right=searchNode->right;
                        succNode->right->parent=succNode;
                }
                transplant(searchNode,succNode);
                succNode->left=searchNode->left;
                succNode->color=searchNode->color;
                succNode->size=searchNode->size;
        }

        delete searchNode;

        if(originalColor==BLACK)
                RBRemoveFixup(x);

        return true;
}
查找第i小关键字:
//返回第i小的元素:
template<class Type>
const Type& orderStatisticTree<Type>::select(int i) const
{
        node* currentNode=root;
        int rank=currentNode->left->size+1;
        while(rank!=i){
                if(i<rank)
                        currentNode=currentNode->left;
                else{
                        currentNode=currentNode->right;
                        i=i-rank;
                }

                rank=currentNode->left->size+1;
        }

        return currentNode->key;
}
返回一个元素的秩:
template<class Type>
int orderStatisticTree<Type>::rank(const Type& val) const
{
        node* searchNode=search(val,root);

        if(searchNode==nullNode)
                throw runtime_error("the element is not existent in the tree.");

        int rank=searchNode->left->size+1;
        node* currentNode=searchNode;
        while(currentNode!=root){
                if(currentNode==currentNode->parent->right)
                        rank+=currentNode->parent->left->size+1;
                currentNode=currentNode->parent;
        }

        return rank;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值