区间树查找算法

一、题目 

  题目:区间树查找算法

  实验目的:实现有效的区间树查找算法

二、算法思想

1、基本概念:

区间:一个事件占用的时间

闭区间:实数的有序对[t1,t2],使t1≤t2

区间的对象表示:[t1,t2]可以用对象i表示,有两个属性:

low[i]=t1//起点或低点

high[i]=t2//终点或高点

区间的重叠:i∩i≠Ø ⇔(low[i]≤high[i]) and (low[i]≤high[i])

2、数据结构:本质上是将红黑树扩充,方法如下:

Step 1:基本结构。以红黑树为基础,对∀x∈T,x包含区间int[x]的信息(低点和高点),key=low[int[x]]。

Step 2:附加信息。max[x]=max(high[int[x]], max[left[x]], max[right[x]])

Step 3:维护附加信息(有效性)。由定理14.1及max的定义⇒有效

Step 4:开发新操作。查找与给定区间重叠的区间keymax节点x

 

3、查找算法IntervalSearch(T, i)基本思想:

step 1:x ←root[T];//从根开始查找

step 2:若x≠nil[T]且i与int[x]不重叠

if x的左子树非空且左子树中最大高点≥low[i] then

x ←left[x];//到x的左子树中继续查找

else //左子树必查不到,到右子树查

x ←right[x];

step 3:返回x //x=nil or i和x重叠

由于区间树是红黑树的简单扩重,因此区间树相关操作的实现如左旋、右旋、插入,插入调整等与红黑树基本相同,具体而言,仅仅在左旋和右旋的操作中维护max域的取值正确即可,其他与红黑树操作完全相同。

本实验中构造的红黑树如下:



P187 图14-4

三、实验结果

四、结果分析

1、中序遍历的结果无误,表明区间树构造正确。

2、查找与区间[3,7]重叠的区间,打印的结果是中序遍历第二个那个节点,结果正确。

3、查找与区间[22,24]重叠的区间,打印的结果是null,表明未找到与此区间重叠的节点,结果正确。

4、查找与区间[21,21]重叠的区间,打印的结果是根节点,结果正确。

    综上,本实验结果符合预期,正确无误,实现了有效的区间树查找算法。

五、总结

  • 查找与i重叠的区间x的过程是现以x为树根开始,逐步下降。当找到一个重叠区域或x指向了nil[T]时,该过程结束。因为基本循环的每次迭代要花O(1)时间,又含n个节点的红黑树的高度为O(lg n),所以区间树查找算法的时间为O(lg n)
  • 先建树,然后插入数据,然后更新,查询。

附件:

源程序:IntervalTreeExperiment.java

/** 
 * @author  
 * Email: 
 * 创建时间:2012-11-16 下午6:44:52
 * 类说明  :区间树查找算法
 * @version 
 */
public class IntervalTreeExperiment {
	public static void main(String[] args) {
		//构造如算法导论书本P187页图14-4的区间树
		IntervalTree it = new IntervalTree();
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(16,21)));
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(8,9)));
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(25,30)));
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(5,8)));
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(15,23)));
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(17,19)));
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(26,26)));
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(0,3)));
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(6,10)));
		IntervalTree.interval_insert(it,new IntervalTreeNode(new Section(19,20)));
    	System.out.println("中序遍历P187页图14-4的区间树:");
    	IntervalTree.inOrderTraverse(it.root);
    	//在此区间树中查找区间[3,7],并输出结果
    	System.out.println("在此区间树中查找区间[3,7]的结果:");
    	System.out.println(IntervalTree.interval_search(it, new Section(3,7)));
    	//在此区间树中查找区间[22,24],并输出结果
    	System.out.println("在此区间树中查找区间[22,24]的结果:");
    	System.out.println(IntervalTree.interval_search(it, new Section(22,24)));
    	//在此区间树中查找区间[21,21],并输出结果
    	System.out.println("在此区间树中查找区间[21,21]的结果:");
    	System.out.println(IntervalTree.interval_search(it, new Section(21,21)));
	}
}
class IntervalTree {
	public int number;
    public IntervalTreeNode root;
    public final static int RED=0;
    public final static int BLACK=1;
	
    public static boolean isOverlap(Section x, Section y){
    	
    	return (x.high>=y.low) && (y.high>=x.low);
    }
	public static IntervalTreeNode interval_search(IntervalTree T,Section i){
		//找出树T中覆盖区间i的那个节点
		IntervalTreeNode x=T.root;
		while(x!=null && !isOverlap(i, x.section)){
			if((x.left != null) && (x.left.max >= i.low)){
				x=x.left;
			}
			else{
				x=x.right;
			}
		}
		return x;
	}
    public static void left_rotate(IntervalTree it,IntervalTreeNode x) {//对x节点左旋转
        if((it==null) || (x==null))return;
        //set y
        IntervalTreeNode y = x.right;
        //turn y's left subtree into x's right subtree
        x.right = y.left;
        if(y.left != null) {
            y.left.p = x;
        }
        //link x's parent to y
        y.p=x.p;
        if(x.p == null) {
            it.root = y;
        }
        else if(x == x.p.left){
            x.p.left=y;
        }
        else {
            x.p.right=y;
        }
        //put x on y's left
        y.left=x;
        x.p=y;
        //update max
        x.max=Math.max(x.section.high, Math.max(x.left.max,x.right.max));
        y.max=Math.max(y.section.high, Math.max(y.left.max,y.right.max));
    }
    public static void right_rotate(IntervalTree it,IntervalTreeNode y) {//对y节点右旋转
        if((it==null) || (y==null))return;
        //set x
        IntervalTreeNode x = y.left;
        //turn x's right subtree into y's left subtree
        y.left=x.right;
        if(x.right != null) {
            x.right.p = y;
        }
        //link y's parent to x
        x.p=y.p;
        if(y.p == null) {
            it.root = x;
        }
        else if(y == y.p.left){
            y.p.left=x;
        }
        else {
            y.p.right=x;
        }
        //put y on x's right
        x.right=y;
        y.p=x;
        //update max
        x.max=Math.max(x.section.high, Math.max(x.left.max,x.right.max));
        y.max=Math.max(y.section.high, Math.max(y.left.max,y.right.max));
    }
    public static void interval_insert(IntervalTree it,IntervalTreeNode z){//在rb中插入z节点
        if(z==null)return;
        IntervalTreeNode y=null;
        IntervalTreeNode x=it.root;
        while(x != null) {
            y=x;
            if(z.key < x.key) {
                x=x.left;
            }
            else {
                x=x.right;
            }
        }
        z.p=y;
        if(y == null) {
            it.root=z;
        }
        else if(z.key < y.key) {
            y.left=z;
        }
        else {
            y.right=z;
        }
        z.left=null;
        z.right=null;
        z.color=RED;
        it.number++;
        rb_insert_fixup(it,z);
    }
    public static void rb_insert_fixup(IntervalTree it,IntervalTreeNode z) {//调整插入后的树
        while((z.p != null) && (z.p.color == RED)){
            if((z.p.p != null) && (z.p == z.p.p.left)) { //父亲节点是祖先节点的左孩子
            	IntervalTreeNode y=z.p.p.right;//uncle y
                if((y != null) && (y.color==RED)) {
                    z.p.color=BLACK;
                    y.color=BLACK;
                    z.p.p.color=RED;
                    z=z.p.p;//important
                }
                else {
                    if(z==z.p.right) {
                        z=z.p;
                        left_rotate(it,z);
                    }
                    z.p.color=BLACK;
                    z.p.p.color=RED;
                    right_rotate(it,z.p.p);
                }
            }
            else if(z.p.p != null){//父亲节点是祖先节点的右孩子
            	IntervalTreeNode y=z.p.p.left;//uncle y
                if((y != null) && (y.color==RED)) {
                    z.p.color=BLACK;
                    y.color=BLACK;
                    z.p.p.color=RED;
                    z=z.p.p;//important
                }
                else {
                    if(z==z.p.left) {
                        z=z.p;
                        right_rotate(it,z);
                    }
                    z.p.color=BLACK;
                    z.p.p.color=RED;
                    left_rotate(it,z.p.p);
                }
            }
            
        }
        it.root.color=BLACK;
    }
//	public static void interval_delete(IntervalTree T,IntervalTreeNode x){}
    public static void inOrderTraverse(IntervalTreeNode root) {
        if(root==null)return;
        inOrderTraverse(root.left);
        if(root.color==RBTree.BLACK) {
            System.out.println(root.section+"\tblack\tmax="+root.max);
        }
        else {
            System.out.println(root.section+"\tred\tmax="+root.max);
        }
        inOrderTraverse(root.right);
    }
}
class IntervalTreeNode {
	public IntervalTreeNode p;
    public IntervalTreeNode left;
    public IntervalTreeNode right;
    public int key;
    public int color;
    //扩展红黑树
	public Section section;
    public int max;
    public IntervalTreeNode(int key){
    	this.key=key;
    }
    public IntervalTreeNode(Section section) {
    	this.section=section;
    	key=section.low; // initialize key
    	max=section.high;// initialize max
    }
	@Override
	public String toString() {
		String color_str;
		if(color==0){
			color_str="red";
		}
		else{
			color_str="black";
		}
		if(p!=null){
			return "IntervalTreeNode [p=" + p.section + ", left=" + left.section + ", right="
				+ right.section + ", color=" + color_str + ", section="
				+ section + ", max=" + max + "]";
	
		}
		else{
			return "IntervalTreeRootNode[left=" + left.section + ", right="
					+ right.section + ", color=" + color_str + ", section="
					+ section + ", max=" + max + "]";
		}
	}
}
class Section{
	public int low;
    public int high;
	public Section(int low, int high) {
		this.low = low;
		this.high = high;
	}
	@Override
	public String toString() {
		return "[" + low + "," + high + "]";
	}
	
}


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值