Segment tree——线段树

线段树

一颗线段树的构造就是根据区间的性质的来构造的, 如下是一棵区间[0, 3]的线段树,每个[start, end]都是一个二叉树中的节点。

[0, 3]的线段树

 

区间划分大概就是上述的区间划分。可以看出每次都将区间的长度一分为二,数列长度为n,所以线段树的高度是log(n),这是很多高效操作的基础。
上述的区间存储的只是区间的左右边界。我们可以将区间的最大值加入进来,也就是树中的Node需要存储leftright左右子节点外,还需要存储start, end, val区间的范围和区间内表示的值。
可以储存不同的值,例如区间内的最大值,最小值,区间的求和等等。

将区间的最大值加入进来

数据结构:

segment tree的创建

class Solution {
public:
    /*
     * @param start: start value.
     * @param end: end value.
     * @return: The root of Segment Tree.
     */
    SegmentTreeNode * build(int start, int end) {
        // write your code here
        
        SegmentTreeNode *root=new SegmentTreeNode(start,end);
        if(start==end) return root;
        else if(start>end) return nullptr;
        else {
            root->left=build(start,(start+end)/2);
            root->right=build((start+end)/2+1,end);
            return root;
        }
        
    }
};

segment tree的查询

class Solution {
public:
    /**
     * @param root: The root of segment tree.
     * @param start: start value.
     * @param end: end value.
     * @return: The maximum number in the interval [start, end]
     */
    int query(SegmentTreeNode * root, int start, int end) {
        // write your code here
        start=max(start,root->start);
        end=min(end,root->end);
        if(root->start==root->end) return root->max;
        int mid=(root->start+root->end)/2;
        int l=query(root->left,start,end);
        
        int r=query(root->right,start,end);
        if(end<=mid) return l;
        else if(start>mid) return r;
        else return max(l,r);
    }
};

segment tree的更新:


class Solution {
public:
    /**
     * @param root: The root of segment tree.
     * @param index: index.
     * @param value: value
     * @return: nothing
     */
    void modify(SegmentTreeNode * root, int index, int value) {
        // write your code here
         if(root->start==root->end&&root->end==index){
            root->max=value;
            return;
        }
        int mid=(root->start+root->end)/2;
        if(index<=mid) modify(root->left,index,value);
        else modify(root->right,index,value);
        root->max=max(root->left->max,root->right->max);
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值