树状数组与线段树

本文详细介绍线段树的数据结构及其实现方法,包括构建线段树的过程、更新节点数据的方法以及查询区间和的操作。通过具体实例展示如何使用线段树解决区间查询问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

推一下关于树状数组的讲解博客:https://blog.youkuaiyun.com/bestsort/article/details/80796531

https://blog.youkuaiyun.com/Small_Orange_glory/article/details/81290634

线段树的讲解:https://blog.youkuaiyun.com/qq_39826163/article/details/81436440

package Test2;

public class _线段树 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		int len = a.length;
		SegTree t = buildtree(0, len - 1, a);
		int sum0_2 = query(t, 0, 2);
		int sum1_3 = query(t, 1, 3);// 查询的和包括左区间和有区间
		System.out.println(sum0_2);
		System.out.println(sum1_3);
	}

	// 构建线段树
	static SegTree buildtree(int l, int r) {
		SegTree segtree = new SegTree(l, r);
		if (l == r) {
			segtree.sum = 0;
			return segtree;
		}
		int mid = (l + r) / 2;
		segtree.lson = buildtree(l, mid);
		segtree.rson = buildtree(mid + 1, r);
		segtree.sum = segtree.lson.sum + segtree.rson.sum;// 也可以求最值
		return segtree;
	}

	// 构建线段树
	static SegTree buildtree(int l, int r, int[] a) {
		SegTree segtree = new SegTree(l, r);
		if (l == r) {
			segtree.sum = a[l];
			return segtree;
		}
		int mid = (l + r) / 2;
		segtree.lson = buildtree(l, mid, a);
		segtree.rson = buildtree(mid + 1, r, a);
		segtree.sum = segtree.lson.sum + segtree.rson.sum;// 也可以求最值
		return segtree;
	}

	// 位置x的数据增量为y
	static void update(SegTree t, int x, int y) {
		if (t == null) {
			return;
		}
		t.sum += y;
		int l = t.l;
		int r = t.r;
		int mid = (l + r) / 2;
		if (x <= mid) {
			update(t.lson, x, y);
		} else {
			update(t.rson, x, y);
		}
	}

	// 查询区间[x,y]的和
	private static int query(SegTree t, int x, int y) {
		// TODO Auto-generated method stub
		int l = t.l;
		int r = t.r;
		if (x <= l && y >= r)
			return t.sum;
		int mid = (l + r) / 2;
		int cnt = 0;
		if (x <= mid) {
			cnt += query(t.lson, x, y);
		}
		if (y > mid) {
			cnt += query(t.rson, x, y);
		}
		return cnt;
	}

	// 单点查询位置
	static int query(SegTree t, int k) {
		int l = t.l;
		int r = t.r;
		if (l == r) {
			return t.sum;
		}
		int mid = (l + r) / 2;
		if (k <= mid) {
			return query(t.lson, k);
		}
		if (k > mid)
			return query(t.rson, k);
		return -1;
	}

}

class SegTree {
	int l, r;// 持有左右区间
	int sum;// 区间和
	SegTree lson;// 左子树
	SegTree rson;// 右子树

	public SegTree(int l, int r) {
		this.l = l;
		this.r = r;
	}
}

递归与非递归的讲解:https://www.cnblogs.com/AC-King/p/7789013.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值