数据结构之线段树

线段树是一颗完美二叉树(perfect Binary Tree),所有的叶子深度都相同并且每个节点要么是叶子要么是有2个儿子的树,树上的每个的节点都是维护一个区间。根维护的是整个区间的最小值,每个节点维护的是父亲区间二等分后的其中一个子区间中的最小值。

线段树主要有2种操作:在给定数列a0,a1,a2,....an-1的情况下,

1. 给定s和t,求as,as+1,.....at的最小值            2.  给定i和x, 把ai的值改成x

 

#define N 1<<16
int n,dat[2*N];
int query(int s,int t,int k,int l,int r)//求(s,t)的最小值,k是节点的编号,l,r对应的是节点k代表的区间[l,r)
{
	int vl,vr;
	if(r<=s||t<=l)//如果[a,b)与[l,r)不相交,返回一个大值
		return INF;
	if(s<=l&&t<=b)//如果[a,b)被[l,r)完全包含,则返回当前节点的值
		return dat[k];
	else//否则返回2个儿子中值的较小值
	{
		vl=query(s,t,k*2+1,l,(l+r)/2);
		vr=query(s,t,k*2+2,l,(l+r)/2);
		return vl>vr?vr:vl;
	}
}
void update(int k,int x)//把ak的值变成x
{
	k+=n-1;//改变第i个节点的值,ai在数组的存储位置是k+n-1    n是叶节点的数量
	dat[k]=x;
	while(k>0)
	{
		k=(k-1)/2;//叶节点的值改变了,其父亲节点的值,也应该相应的变化
		dat[k]=min(dat[k*2+1],dat[k*2+2]);
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值