下面给出了区间类定义,区间树类的结点结构,左旋,右旋,恢复插入引起的红黑树性质破坏,插入,恢复删除引起的红黑树性质破坏,删除,寻找重叠区间,寻找重叠区间但具有最小低端点,寻找重叠区间但具有最大低端点这一系列操作的代码。
区间类定义:
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&¤tNode->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;
}