线段树解析以及代码模板

线段树的概念

线段树是一种二叉搜索树,线段树的每个节点存了一个区间,所以得名。线段树如果是非叶子节点一定有两个子节点,如果有左子树那么就一定有右子树。

主要应用是区间最大值以及区间最小值以及区间求和,区间更新。


线段树的数据域

一般存储区间的和,以及区间的最大值,最小值等等。


线段树的操作

以区间求值为例子
struct Node
{
	int begin,end;
	Node *left;
	Node *right; 
	int sum;
	Node(int a,int b,int s):begin(a),end(b),sum(s){}
}


//构造树
Node * buildTree(vector<int>&nums,int begin ,int end )
{
	Node *root=NULL;
	if(begin==end)
	{
		root=new Node(begin,end,nums[begin]);
		return root;
	}
		
	Node* l=buildTree(nums,begin,begin+(end-begin)/2);
	Node* r=buildTree(nums,begin+(end-begin)/2+1,end);


	root=new Node(begin,end,l->sum+r->sum);
	root->left=l;
	root->right=r;


	return root;
}




//查询树
int queryTree(int i,int j,Node * root)
{
	if(root==NULL)
		return 0;
	if(root->begin<=i&&root->end<=j)
		return root->sum;
	int mid=root->begin+(root->end-root->begin)/2;


	int lsum=0;
	int rsum=0;
	if(i<=mid)
		lsum=query(i,j,root->left);
	if(j>mid)
		rsum=query(i,j,root->right);
	return lsum+rsum;
}




int updateTree(int i,int val,Node * root)
{
	int diff=0;
	if(root->begin==i&&root->end==i)
	{
		diff=val-root->sum;
		root->sum=val;
	}
	int mid=root->begin+(root->end-root->begin)/2;
	if(i<=mid)
		diff=updateTree(i,val,root->left);
	if(i>mid)
		diff=updateTree(i,val,root->right);


	root->sum+=diff;
	return diff;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值