线段树(求区间极值)

public class SegTree {
    private static int[] base = {5, 9, 7, 4, 6, 1};
    private static segNode[] nodes = new segNode[(base.length << 1) + 2];//n个叶节点,n-1个度为2的节点

    public static void main(String[] args) {
        build(0);
        int max = query(0, 3, 5);
        System.out.println(max);
        updateOne(0,4,5);
        max = query(0, 3, 5);
        System.out.println(max);
    }

    /**
     * 创建线段树
     *
     * @param index 节点下标
     */
    public static void build(int index) {
        segNode node = nodes[index];//取出node
        if (node == null) {//创建根节点
            nodes[index] = new segNode(0, base.length - 1);
            node = nodes[index];
        }
        if (node.start == node.end) {//如果是左端点等于右端点
            node.val = base[node.start];
        } else {//否则创建左右节点
            int mid = (node.end + node.start) >> 1;
            nodes[(index << 1) + 1] = new segNode(node.start, mid);//左子树
            nodes[(index << 1) + 2] = new segNode(mid + 1, node.end);//右子树
            build((index << 1) + 1);
            build((index << 1) + 2);
            node.val = Math.max(nodes[(index << 1) + 1].val, nodes[(index << 1) + 2].val);
        }
    }

    /**
     * 线段树的区间查找
     *
     * @param index: 节点下标
     * @param start: 查找区间的左端点
     * @param end:   查找区间的右端点
     * @return: 区间最大值
     */
    public static int query(int index, int start, int end) {
        segNode node = nodes[index];//取出来
        if (node.start > end || node.end < start)//在区间之外
            return Integer.MIN_VALUE;//返回最小值
        if (node.start >= start && node.end <= end)//在区间内
            return node.val;
        else {//部分在区间内(递归左右子树)
            return Math.max(query((index << 1) + 1, start, end), query((index << 1) + 2, start, end));
        }
    }

    /**
     * 单点更新
     * @param index
     * @param update
     * @param val
     */
    public static void updateOne(int index, int update, int val) {
        segNode node = nodes[index];
        if (node.start == node.end && node.start == update) {//找到目标节点
            node.val = val;
        }else {//否则,继续往下找,并且记得更新父节点
            int mid = (node.start+node.end) >> 1;
            if (update <= mid)
                updateOne((index<<1)+1,update,val);
            else
                updateOne((index<<1)+2,update,val);
            node.val = Math.max(nodes[(index<<1)+1].val,nodes[(index<<1)+2].val);
        }
    }


}

class segNode {
    int val;
    int start;
    int end;

    public segNode(int start, int end) {
        this.start = start;
        this.end = end;
    }

    @Override
    public String toString() {
        return "segNode{" +
                "val=" + val +
                '}';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值