数据结构:线段树
来源:互联网 发布:淘宝网苹果4手机 编辑:程序博客网 时间:2024/06/14 11:51
(1)构建
LintCode:Link
线段树是一棵二叉树,他的每个节点包含了两个额外的属性start
和end
用于表示该节点所代表的区间。start和end都是整数,并按照如下的方式赋值:
- 根节点的 start 和 end 由
build
方法所给出。 - 对于节点 A 的左儿子,有
start=A.left, end=(A.left + A.right) / 2
。 - 对于节点 A 的右儿子,有
start=(A.left + A.right) / 2 + 1, end=A.right
。 - 如果 start 等于 end, 那么该节点是叶子节点,不再有左右儿子。
实现一个 build
方法,接受 start 和 end 作为参数, 然后构造一个代表区间 [start, end]
的线段树,返回这棵线段树的根。
/** * Definition of SegmentTreeNode: * public class SegmentTreeNode { * public int start, end; * public SegmentTreeNode left, right; * public SegmentTreeNode(int start, int end) { * this.start = start, this.end = end; * this.left = this.right = null; * } * } */public class Solution { /* * @param start: start value. * @param end: end value. * @return: The root of Segment Tree. */ public SegmentTreeNode build(int start, int end) { SegmentTreeNode node = null; if(start==end){ node = new SegmentTreeNode(start, end); } if(start<end){ node = new SegmentTreeNode(start, end); int m = (start+end)/2; SegmentTreeNode left = build(start, m); SegmentTreeNode right = build(m+1, end); node.left = left; node.right = right; } return node; }}
(2)查询区间最大值
LintCode:Link
对于一个有n个数的整数数组,在对应的线段树中, 根节点所代表的区间为0-n-1, 每个节点有一个额外的属性max
,值为该节点所代表的数组区间start到end内的最大值。
为SegmentTree设计一个 query
的方法,接受3个参数root
, start
和end
,线段树root所代表的数组中子区间[start, end]内的最大值。
package com.graph;import java.util.*;import javax.security.auth.kerberos.KerberosKey;import java.util.*;class SegmentTreeNode { public int start, end, max; public SegmentTreeNode left, right; public SegmentTreeNode(int start, int end, int max) { this.start = start; this.end = end; this.max = max; this.left = this.right = null; }}public class Solution { public int query(SegmentTreeNode root, int start, int end) { if(root.start==start && root.end==end){//刚好在该区间内 return root.max; } int m = (root.start+root.end)/2; int leftMax=Integer.MIN_VALUE; int rightMax=Integer.MIN_VALUE; if(end<=m){//在左子树 leftMax = query(root.left, start, end); }else if(m+1<=start){//在右子树 rightMax = query(root.right,start, end); }else{//横跨左右子树 leftMax = query(root.left, start, m); rightMax = query(root.right, m+1, end); } return Math.max(leftMax, rightMax); } int[] maxnums = new int[] {3,2,2,1,3,0,3}; int maxIndex=0; public SegmentTreeNode build(int start, int end) { SegmentTreeNode node = null; if(start==end){ node = new SegmentTreeNode(start, end, maxnums[maxIndex++]); } if(start<end){ node = new SegmentTreeNode(start, end, maxnums[maxIndex++]); int m = (start+end)/2; SegmentTreeNode left = build(start, m); SegmentTreeNode right = build(m+1, end); node.left = left; node.right = right; } return node; } public static void main(String[] args) {Solution s = new Solution();SegmentTreeNode root = s.build(0,3,0);s.query(root, 0, 2);}}
(3)修改线段树
LintCode:Link
对于一棵 最大线段树, 每个节点包含一个额外的 max
属性,用于存储该节点所代表区间的最大值。
设计一个 modify
的方法,接受三个参数 root
、 index
和 value
。该方法将 root 为跟的线段树中 [start, end] = [index, index] 的节点修改为了新的 value ,并确保在修改后,线段树的每个节点的 max 属性仍然具有正确的值。
/** * Definition of SegmentTreeNode: * public class SegmentTreeNode { * public int start, end, max; * public SegmentTreeNode left, right; * public SegmentTreeNode(int start, int end, int max) { * this.start = start; * this.end = end; * this.max = max * this.left = this.right = null; * } * } */public class Solution { /* * @param root: The root of segment tree. * @param index: index. * @param value: value * @return: */ public void modify(SegmentTreeNode root, int index, int value) { update(root, index, index, value); } boolean update(SegmentTreeNode node, int s, int e, int value){ if(node.start==s && node.end==e){ node.max=value; return true; } boolean flag1=false, flag2=false; int m = (node.start+node.end)/2; if(e<=m){ flag1 = update(node.left, s, e, value); }else if(m+1<=s){ flag1 = update(node.right, s, e, value); }else{ flag1 = update(node.left, s, m, value); flag2 = update(node.right, m+1, e, value); } if(flag1 || flag2){ int tmpMax = node.max; node.max = Math.max(node.left.max, node.right.max); if(tmpMax!=node.max) return true;//node的值更新了 else return false; }else{ return false; } } }
阅读全文
0 0
- 【数据结构】线段树专辑
- [数据结构]线段树专辑
- 数据结构之线段树
- 数据结构之线段树
- 数据结构:线段树
- 数据结构之线段树
- 数据结构:线段树
- 数据结构:线段树
- 数据结构:线段树
- 数据结构之线段树
- 数据结构之线段树
- 数据结构之线段树
- 数据结构:线段树
- 模板:(数据结构:线段树)
- 数据结构之线段树
- [数据结构]线段树
- 数据结构之线段树
- [数据结构]线段树
- C++学习流程
- 有关C语言联合体(union)的使用
- ADMM算法相关资源
- Ubuntu16.04 安装Mysql 设置远程访问
- 自用sqlhelper
- 数据结构:线段树
- JAVA学习54_ JAVA 正则表达式
- JSP九大隐含对象中的Exception
- OpenGL蓝宝书Move--碰撞检测
- Java环境搭建,以win10为例
- python模块
- 【JZOJ5307】【NOIP2017提高A组模拟8.18】偷窃
- A
- ==和equals的区别