• 区间树查找


    #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

  • 相关阅读:
    填坑总结:python内存泄漏排查小技巧
    springMVC注解中@RequestMapping中常用参数value params 以及@RequestParam 详解
    springMVC 自定义类型转换器
    为什么Java需要lambda 表达式? 上帝爱吃苹果
    利器| Cypress 强大全新的 Web UI 测试框架应用尝鲜
    缺少锻炼面试的机会?城市群之北上广杭一起来了!
    实战 | 基于JMeter 完成典型电商场景(首页浏览)的性能压测
    一文搞定 pytest 自动化测试框架(一)
    测试面试 | Java 经典面试题汇总
    软件测试工程师成长痛点和职业发展建议
  • 原文地址:https://www.cnblogs.com/sunshinewill/p/2943708.html
Copyright © 2020-2023  润新知