线段树的建树、修改单点值、计算区间和

线段树用途:可以在O(log n)的时间复杂度内求得区间和并修改单点值

建树

void buildSegmentTree(vector<int>& nums, vector<int>& segmentTree, int node, int start, int end) {
    // node 是线段树的结点编号, [start, end]是线段树结点对应的 nums 中的区间范围
	if (start == end) {
		segmentTree[node] = nums[start];
		return;
	}
	int leftNode = 2 * node + 1;  // 左孩子
	int rightNode = 2 * node + 2;  // 右孩子
	int mid = start + (end - start) / 2;
	buildSegmentTree(nums, segmentTree, leftNode, start, mid);
	buildSegmentTree(nums, segmentTree, rightNode, mid + 1, end);
	segmentTree[node] = segmentTree[leftNode] + segmentTree[rightNode];
}

修改单点值

void update(vector<int>& nums, vector<int>& tree, int node,int start, int end, int idx, int val) {
    // 要将 nums[idx] 修改为 val
	if (start == end) {
		nums[idx] = val;
		tree[node] = nums[start];
		return;
	}
	int leftNode = 2 * node + 1;
	int rightNode = 2 * node + 2;
	int mid = start + end >> 1;
	if (idx <= mid) {
		update(nums, tree, leftNode, start, mid, idx, val);
	}
	else {
		update(nums, tree, rightNode, mid + 1, end, idx, val);
	}
	tree[node] = tree[leftNode] + tree[rightNode];
}

计算区间和

int query(vector<int>& nums, vector<int>& segmentTree, int node, int start, int end, int l, int r) {
    // 计算区间[l, r]的元素之和
	if (r < start || l > end) {
		return 0;
	}
	else if (l <= start && r >= end) {
		return segmentTree[node];
	}
	int leftNode = 2 * node + 1;
	int rightNode = 2 * node + 2;
	int mid = start + (end - start) / 2;
	int leftSum = query(nums, segmentTree, leftNode, start, mid, l, r);
	int rightSum = query(nums, segmentTree, rightNode, mid + 1, end, l, r);
	return leftSum + rightSum;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值