简介
线段树是一种二叉搜索树,是用来维护区间信息的数据结构。可以在O(logN)的时间复杂度内实现单点修改、区间修改、区间查询(区间求和,求区间最大值,求区间最小值)等操作。接下来我以实现区间求和为例子来讲解线段树(最大值和最小值与求和实现方式几乎无异),假设存在一个数组[1,4,6,3,9]。
实现思路
从线段树的定义,我们首先需要定义一个树节点,节点包含区间和(23),区间([1-5]),左节点,右节点等。(如果要实现求区间最大值,最小值,则还需包含这些)。然后需要提供构建线段树,线段树支持修改节点操作方法。
节点定义
@Data
public static class Node {
//区间起始下标
private int start;
//区间结尾下标
private int end;
//当前区间和值
private int value;
private Node left;
private Node right;
Node(int start, int end, int value) {
this.start = start;
this.end = end;
this.value = value;
}
}
构建线段树
因为构建线段树时候需要计算当前区间和,所以我们可以先初始化一个前缀和数组,在构建线段树时候利用下标快速计算出区间和,同时为了保证每个节点有一致的操作,初始化一个头节点,指向root(这是链表树等常用的简化操作的方法)
//head 指向线段树root节点的指针,使得root节点与其余节点操作保持一致
Node head;
int size;
List<Integer> nums;
// 前缀和数组,便于构建线段树时候计算区间值,用于初次构建辅助
List<Integer> prefixSum;
public void init(List<Integer> nums) {
//初始化一个头节点,便于操作
this.head = new Node(-1, -1, -1);
this.nums = nums;
//初始化前缀和数组
prefixSum =