线段树 详解

1. 线段数是二叉树 .线段数是递归定义的。则知道线段数的所有操作都是递归的

2. 在定义的时候定义的是节点。而一棵树是由  struct Node{ 

  很多的节点连接起来的                      int min, max, sum,left,right; Node *left_child, *right_child; }

3. 综上可知。线段数可以采用动态和静态2种链表的方法   

4. 线段数也可以使用数组模拟 int left[], right[] ,left_child[] ,right_child[] ;

5. 类似于堆存储 除了最底层外是满二叉树。则节点 i 的做孩子在 2*i 有孩子在2*i+1(缺点是可能很浪费空间)

       

定义代码如下(c++)                                查询代码如下(c++)   分割符号 | f分隔的 doc上看就好了。

Void Build( Node * cur ,int l, int r) {       | void Query(Node *cur, int l ,int r) {

cur->left=l; cur->right=r; | Node *Lc=cur->left_child, *Rc=cur->right_child;

If(l!=r) { | if((l<=cur->left)&&(cur->right<=r)) //覆盖了

cur->left_child=new Node; | printf("%d%d",cur->left,cur->right);

cur->right_child=new Node; | esle {

Build(cur->left_child,l,(l+r)/2); | if(l<=(cur->left+cur->right)/2) Query(Lc,l,r);

Build(cur->right_child,(l+r)/2+1,r); | if(r>(cur->left+cur->right)/2) Query(Rc,l,r);

} else cur->left_child=cur->right_child=Null; | }

} | }

查询 过程其实仅仅是提供一个将查询区间分解的过程

1.当前节点表示的区间包含于查询区间 则该区间就是要分解的区间

2.否则 递归 查询 左 右孩子

(By the way:解释下节点的 min ,max , sum ) start

定义目前工作的数组是 int work[i]; a<=i<=b; node[k];代表第k个节点

Node[k].min = min( work[i] ) a<=i<=b; min 和 max是在插入的时候更新的所以 用的时候直接取就是 

Sum 就是∑work(i)  end

线段数的  修改 Update 

void Insert ( Node *cur, int i ,int v)  {  //将i位置的值修改为V

Node *Lc =cur ->left_child, *Rc =cur->right_child ;

if(cur->left == i && cur->right ==i) // 改成( cur->left==cur->right ) 可以减少一次运算 

cur->min=cur->max=v;

else {

If( i<=(cur->left+cur->right)/2)  Insert (Lc , i , v) ;

  If( i> (cur->left+cur->right) /2 )   Insert (Rc, i , v );

Cur.sum = Lc->sum+ Rc->sum;

Cur.min = Lc->min<?Rc->min ;

Cur.max = Lc->max>?Rc->max ;

}

}

线段数的 查询(查询 sum) (区间 a-b)之间 有返回值 不是 void

int Qsum( Node * cur ,int l, int r) {

Node *Lc = cur->left_child , *Rc =cur ->right_child;  int temp(0) ;

If ( ( l<= cur->left )&&( r>= cur->right))temp+=cur.sum;

Else {

If( l<= (cur->left +cur->right)/2)  temp+=Qsum(Lc , l ,r);

If( r> (cur->left + cur->right)/2)   temp+=Qsum(Rc, l, r);

Return temp;

}

最后只想说一句。那些所谓的节点所代表的区间就是你工作数组的下标。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值