区间树查找
#include<iostream> #include<queue> using namespace std; struct rbnode{ int key;//key值即为low点值 int color;//1=black,0=red; int max,high;//在每次旋转后更新max struct rbnode *p,*left,*right; rbnode(){} rbnode(int k,int hi){key=k;high=hi;max=hi; } }; rbnode *nil; int max(int a,int b) {return a>b?a:b;} int mmax(rbnode * a){ int xx=-1,yy=-1,zz=-1; if(a!=nil)xx=a->high;else return -1; if(a->left!=nil)yy=a->left->max; if(a->right!=nil)zz=a->right->max; return max(max(xx,yy),zz);} rbnode * Minintervalsearch(rbnode **root,rbnode *x,int i1,int i2); bool RBinsert(rbnode **root,int k,int high); void Fixmax(rbnode **root,int num,int high); void LevelOrder(rbnode *t); void RBinserFix(rbnode **root,rbnode *z); void Left(rbnode **root, rbnode *x); void Right(rbnode **root, rbnode *x); void Left(rbnode **root, rbnode *x){ if(x->right!=nil){ rbnode * y=nil; y=x->right; x->right=y->left; if(y->left!=nil)y->left->p=x; y->p=x->p; if(x->p==nil) (*root)=y; else if(x==x->p->left) x->p->left=y; else x->p->right=y; y->left=x; x->p=y;} } void Right(rbnode **root, rbnode *x){ if(x->left!=nil){ rbnode * y=nil; y=x->left; x->left=y->right; if(y->right!=nil)y->right->p=x; y->p=x->p; if(x->p==nil) (*root)=y; else if(x==x->p->right) x->p->right=y; else x->p->left=y; y->right=x; x->p=y; } } void RBinserFix(rbnode **root,rbnode *z){ rbnode* y=nil; while(z!=*root&&z->p->color==0){ if(z->p==z->p->p->left){ y=z->p->p->right; if(y->color==0){ z->p->color=1; y->color=1; z->p->p->color=0; z=z->p->p; }else { if(z==z->p->right){z=z->p;//LEFT Left(root,z); ////////////////////////////////////////////// z->max=mmax(z); z->p->p->max=mmax(z->p->p); } z->p->color=1; z->p->p->color=0; //RightRotate(); Right((root),z->p->p); /////////////////////////////////////////////////////// if(z->p!=nil){//z->p不能为nil,否则z->p->left为空 z->p->max=mmax(z->p); z->p->right->max=mmax(z->p->right); } } }else { y=z->p->p->left; if(y->color==0){ z->p->color=1; y->color=1; z->p->p->color=0; z=z->p->p; }else { if(z==z->p->left){z=z->p;//LEFT Right(root,z); z->max=mmax(z); z->p->p->max=mmax(z->p->p); } z->p->color=1; z->p->p->color=0; //RightRotate(); Left((root),z->p->p);} if(z->p!=nil) { z->p->max=mmax(z->p); z->p->left->max=mmax(z->p->left); } } } (*root)->color=1; } //调节max方法 void Fixmax(rbnode **root,int k,int high){ rbnode* x=*root; while(x!=nil){ if(x->max<high)x->max=high; if(k==x->key)break; if(k<x->key)x=x->left; else x=x->right; } } rbnode* Minintervalsearch(rbnode **root,rbnode *x,int i1,int i2){ rbnode* y=nil; if(x==nil)return nil; if(x->left!=nil&&x->left->max>=i1) {y=Minintervalsearch(root,x->left,i1,i2); if(y!=nil)return y; else if((x->key<=i1&&x->high>=i1)||(x->key<=i2&&x->high>=i2)||(x->key>=i1&&x->key<=i2))return x; else return nil; } else if((x->key<=i1&&x->high>=i1)||(x->key<=i2&&x->high>=i2)||(x->key>=i1&&x->key<=i2))return x; else return Minintervalsearch(root,x->right,i1,i2); } bool RBinsert(rbnode **root,int k,int high){ rbnode* z=new rbnode(k,high); //cout<<root->color; rbnode* y=nil; rbnode* x=*root; while(x!=nil){ y=x; if(k==x->key)return 0; if(k<x->key)x=x->left; else x=x->right; } z->p=y; if(y==nil) {(*root)=z;(*root)->p=nil;} else if(k<y->key) y->left=z; else y->right=z; z->left=nil;z->right=nil; z->color=0; //LevelOrder(*root); RBinserFix(root,z); return 1; } void Visit(rbnode *t) { if (t) { cout << t->key<<'.'<<t->high<<'.'<<t->max; if(t->color)cout<<"黑 "; else cout<<"红 "; } } void LevelOrder(rbnode *t) {// 对* t逐层遍历 queue<rbnode*> Q; while (t!=nil) { Visit(t); if (t->left!=nil) Q.push(t->left); if (t->right!=nil) Q.push(t->right); if (Q.empty()) break; t=Q.front(); Q.pop(); } } void main(){ //rbnode* root= //root->color=1;//1=black //root->p=nil; //root->left=nil;root->right=nil; rbnode** root=(rbnode**)malloc(sizeof(rbnode*));; nil=new rbnode(); nil->color=1; *root =nil; rbnode* y=nil; //rbnode cout<<"输入操作类型:1插入元素 2输出结构 3区间树查找 4退出"<<endl; int sinin,num,high; cin>>sinin; while(sinin!=4) {switch(sinin){ case 1: cout<<"插入: "; cin>>num>>high; if(num>=high){cout<<"数据范围有问题,重新输入"<<endl;break;} if(!RBinsert(root,num,high))cout<<"插入重复值"<<endl; else Fixmax(root,num,high); // cout<<" root --key:"<<(*root)->p->color<<endl; break; case 2: LevelOrder(*root); cout<<endl; break; case 3: cin>>num>>high; y=Minintervalsearch(root,*root,num,high); if(y!=nil) cout<<y->key<<" "<<y->high<<endl; else cout<<"结果为空"<<endl; break; }cout<<"输入操作类型:1插入元素 2输出结构 3区间树查找 4退出"<<endl; cin>>sinin; } }
区间树,在红黑树的基础上对其进行拓展,增加max域,上限high域,下限key值。利用原key值表示区间的下限,并将key值作为插入时比较的值。通过max来对左子树、右子树及该节点的区间上限做出描述。
查找时,返回与查找区间重叠的最小低端区间,若不存在返回nil,伪代码如下:
MIN-INTERVAL-SEARCH(T,x,i)
{ if left[x]!=nil[T] and max[left[x]]>=low[i]//左子树不为空,且高点大于i低点
{ y=MIN-INTERVAL-SEARCH(T,left[x],i)
if y!=nil return y
else if i overlaps int[x] return x//如果左子树为空则查看节点x,不重叠返回nil
else return nil
}
else if i overlaps int[x]//节点x是否与i重叠
return x
else return MIN-INTERVAL-SEARCH(T,right[x],i) //对x节点右子树调用该方法
}
修改原rbtree节点结构增加high与max值,修改原rbtree的插入方法,插入时指出插入区间范围。插入区间依次为:
[0,3][5,8][6,10][8,9][15,23][16,21]。按层次遍历方法输出区间树结构如下:
输出顺序依次为该节点的范围区间,范围最大值及颜色。
对该结构区间树,进行区间查找操作,具体过程如下:(返回与输入区间重叠的最小低端区间)
查找区间[1,2],相应返回重叠区间为[0,3]
原文链接:http://www.cnblogs.com/sunshinewill/archive/2013/03/05/2943708.html