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

来源:互联网 发布:金钻js防水 编辑:程序博客网 时间:2024/05/16 00:35

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

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

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

动态顺序统计:

下面代码给出了左旋,右旋,恢复插入引起的红黑树性质的破坏,插入,恢复删除引起的红黑树性质的破坏,删除,查找第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
原创粉丝点击