线段树和区间树

本文介绍了如何使用线段树和区间树解决区间重叠问题。针对给定的线段集合,通过构建二叉排序树减少搜索复杂度,实现了高效的线段重叠检查。同时,文章提供了具体的算法思路和代码实现,进一步阐述了线段树在计算合并线段长度和解决覆盖面积问题上的应用。
摘要由CSDN通过智能技术生成

区间树 

问题描述1:

假如有四个线段 { 1, 2 }, { 2, 4 }, { 1, 3 }, { 4, 9 } ,问线段(3, 4)与这些线段中有几个是重叠的?

   分析:按照正常思路是先遍历,依次比对左端点3是否在某个线段中,右端点是否在某个线段中, 如果只有四个线段的话这个是推荐的。但是一旦数据量大了复杂度就高,这时我们需要利用二分查找的思想来判断。

  我们先构造一个树,使得只需要判断根节点就知道需不需要搜寻子节点了。比如某个子树最右边是2,那么3,4肯定不会与这些子树下面的线段冲突,这就大大减少了需要查找的数据量。

算法思路:

  1. 构造二叉排序树,以线段左端点作为排序条件。每添加一个节点更新各子树可到的最右端距离
  2. 计算重合:如果目标线段左端点大于当前节点子树可到的最大右端点则返回0.如果目标线段与当前节点线段重合则重合数+1,交给左右节点去计算重合的数量。最终的重合数量是左右节点重合数量之和加当前节点是否与目标节点重合

具体代码

public class LineSegmentTree {
	public int begin;
	public int end;
	public int max_right;
	LineSegmentTree left;
	LineSegmentTree right;

	public LineSegmentTree(int begin, int end) {
		this.begin = begin;
		this.end = end;
//一开始只有一个节点,因此自己作为根节点子树可到的最右端是自己的右端点
		max_right = end;

	}

	private void add(LineSegmentTree child) {
		if (child.begin < begin) {
			if (left == null)
				left = child;
			else
				left.add(child);
		} else {
			if (right == null)
				right = child;
			else
				right.add(child);
		}
//更新当前节点为根节点的子树可到的最右端距离
		if (left != null && left.max_right > max_right)
			max_right = left.max_right;
		if (right != null && right.max_right > max_right)
			max_right = right.max_right;
	}

	public int getCollisionNum(int tbegin, int tend) {
//如果目标节点起始点比当前子树可到最右端还要大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值