第14章 数据结构扩张 区间树部分代码

下面给出了区间类定义,区间树类的结点结构左旋右旋恢复插入引起的红黑树性质破坏插入恢复删除引起的红黑树性质破坏删除寻找重叠区间寻找重叠区间但具有最小低端点寻找重叠区间但具有最大低端点这一系列操作的代码。

区间类定义:
class interval{
public:
        interval(const int& l=int(),const int& h=int()):lowEndPoint(l),highEndPoint(h){}
        friend bool operator<(const interval&,const interval&);//重新加载小于操作符
        friend class intervalTree;//将区间树定义为友元,以便调用interval类的私有数据成员。 
private:
        int lowEndPoint;
        int highEndPoint;
};
inline bool operator< (const interval& lhs,const interval& rhs) { return lhs.lowEndPoint<rhs.lowEndPoint; }//是依据区间低端点来比较两个区间的大小
结点结构:
struct node{
                interval element;
                node* parent;
                node* left;
                node* right;
                int color;
                int maxEndPoint;//某一子树(包括该子树根)中所有区间端点的最大值。
                node(const interval& e=interval(),node* p=0,node* l=0,node* r=0,int c=BLACK,int m=INT_MIN):element(e),parent(p),left(l),right(r),color(c),maxEndPoint(m){}
        };
左旋:
void intervalTree::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;
//上述代码和红黑树一样,下面两行代码是对maxEndPoint这一附加信息的维护。
        x->maxEndPoint=maximum(x->element.highEndPoint,x->left->maxEndPoint,x->right->maxEndPoint);
        y->maxEndPoint=maximum(y->element.highEndPoint,y->left->maxEndPoint,y->right->maxEndPoint);
}
右旋:
void intervalTree::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;
//上述代码和红黑树一样,下面两行代码是对maxEndPoint这一附加信息的维护。
        x->maxEndPoint=maximum(x->element.highEndPoint,x->left->maxEndPoint,x->right->maxEndPoint);
        y->maxEndPoint=maximum(y->element.highEndPoint,y->left->maxEndPoint,y->right->maxEndPoint);
}
恢复插入引起的红黑树性质破坏:
void intervalTree::RBInsertFixup(node* currentNode)
{
        node* tmp=currentNode->parent;
        while(tmp!=nullNode){
                tmp->maxEndPoint=maximum(tmp->element.highEndPoint,tmp->left->maxEndPoint,tmp->right->maxEndPoint);
                tmp=tmp->parent;
        }//对从currentNode到根这一路径上所有结点的maxEndPoint这一性质的维护

        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);
                                         leftRotate(currentNode->parent->parent);
                        }
                }
        }
        root->color=BLACK;
}
插入:
//和红黑树插入操作几乎一样;
void intervalTree::insert(const interval& val)
{
        node* prevNode=nullNode;
        node* currentNode=root;

        while(currentNode!=nullNode){
                prevNode=currentNode;
                if(val<currentNode->element)
                        currentNode=currentNode->left;
                else
                        currentNode=currentNode->right;
        }

        if(prevNode==nullNode)
                root=new node(val,nullNode,nullNode,nullNode,BLACK,val.highEndPoint);
        else if(val<prevNode->element){
                prevNode->left=new node(val,prevNode,nullNode,nullNode,RED,val.highEndPoint);
                RBInsertFixup(prevNode->left);
        }
        else{
                prevNode->right=new node(val,prevNode,nullNode,nullNode,RED,val.highEndPoint);
                RBInsertFixup(prevNode->right);
        }
}
恢复删除引起的红黑树性质破坏:
 node* tmp=currentNode->parent;
        while(tmp!=nullNode){
                tmp->maxEndPoint=maximum(tmp->element.highEndPoint,tmp->left->maxEndPoint,tmp->right->maxEndPoint);
                tmp=tmp->parent;
        }//对从currentNode到根这一路径上所有结点的maxEndPoint这一性质的维护


        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;
}
删除:
//和红黑树删除操作几乎一样
bool intervalTree::remove(const interval& val)
{
        node* searchNode=search(val,root);
        if(searchNode==nullNode)
                return false;

        node* nextNode=0;
        int originalColor;

        if(searchNode->left==nullNode){
                nextNode=searchNode->right;
                originalColor=searchNode->color;
                transplant(searchNode,searchNode->right);
        }
        else if(searchNode->right==nullNode){
                nextNode=searchNode->left;
                originalColor=searchNode->color;
                transplant(searchNode,searchNode->left);
        }
        else{
                node* succNode=findMin(searchNode->right);
                nextNode=succNode->right;
                originalColor=succNode->color;

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

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

        delete searchNode;
        return true;
}
寻找重叠区间:
bool intervalTree::isOverlap(const interval& lhs,const interval& rhs) const
{
        return !(lhs.highEndPoint<rhs.lowEndPoint||rhs.highEndPoint<lhs.lowEndPoint);
}
//返回碰到的第一个重叠区间
void intervalTree:: searchOverlap(const interval& val) const
{
        node* currentNode=root;

        while(currentNode!=nullNode&&!isOverlap(currentNode->element,val)){
                if(currentNode!=nullNode&&val.lowEndPoint<=currentNode->left->maxEndPoint)
                        currentNode=currentNode->left;
                else
                        currentNode=currentNode->right;
        }

        if(currentNode==nullNode)
                throw runtime_error("the overlappint intervals are not existent.");

        cout<<"lowEndPoint: "<<currentNode->element.lowEndPoint<<"\t"<<"highEndPoint: "<<currentNode->element.highEndPoint<<endl;
}
寻找重叠区间但具有最小低端点:
intervalTree::node* intervalTree::lessLowEndPointOverlap(const interval& val,node* rootNode) const
{
        if(rootNode==nullNode)
                return nullNode;

        if(rootNode->left!=nullNode&&val.lowEndPoint<=rootNode->left->maxEndPoint){
                node* tmp=lessLowEndPointOverlap(val,rootNode->left);
                if(tmp!=nullNode)
                        return tmp;
                else if(isOverlap(val,rootNode->element))
                        return rootNode;
                else return nullNode;
        }
        else if(isOverlap(val,rootNode->element))
                return rootNode;
        else
                return lessLowEndPointOverlap(val,rootNode->right);
}

void intervalTree::lessLowEndPointOverlap(const interval& val) const
{
        node* tmp=lessLowEndPointOverlap(val,root);

        if(tmp==nullNode)
                throw runtime_error("there are not overlapping intervals");

        cout<<"lowEndPoint: "<<tmp->element.lowEndPoint<<"\t"<<"highEndPoint: "<<tmp->element.highEndPoint<<endl;
}
寻找重叠区间但具有最大低端点:
intervalTree::node* intervalTree::largestLowEndPointOverlap(const interval& val,node* rootNode) const
{
        if(rootNode==nullNode)
                return nullNode;

        if(rootNode->right!=nullNode&&val.lowEndPoint<=rootNode->right->maxEndPoint){
                node* tmp=largestLowEndPointOverlap(val,rootNode->right);

                if(tmp!=nullNode)
                        return tmp;
                else if(isOverlap(val,rootNode->element))
                        return rootNode;
                else
                        return largestLowEndPointOverlap(val,rootNode->left);
        }
        else if(isOverlap(val,rootNode->element))
                return rootNode;
        else
                return largestLowEndPointOverlap(val,rootNode->right);
}

void intervalTree::largestLowEndPointOverlap(const interval& val) const
{
        node* tmp=largestLowEndPointOverlap(val,root);

        if(tmp==nullNode)
                throw runtime_error("there are not overlapping intervals");

        cout<<"lowEndPoint: "<<tmp->element.lowEndPoint<<"\t"<<"highEndPoint: "<<tmp->element.highEndPoint<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值