目录
讲解一:线段树
一、基本介绍
线段树(又名区间树)也是一种二叉树,每个节点的值等于左右孩子节点值的和,线段树示例图如下
以求和为例,根节点表示区间0-5的和,左孩子表示区间0-2的和,右孩子表示区间3-5的和,依次
类推。
二、基本方法
1. 线段树构建
private void buildTree(int treeIndex, E[] source, int left, int right) {
if (left == right) {
data[treeIndex] = new Node<>(source[left], left, right);
return;
}
int leftTreeIndex = leftChild(treeIndex);
int rightTreeIndex = rightChild(treeIndex);
int middle = left + ((right - left) >> 1);
buildTree(leftTreeIndex, source, left, middle);
buildTree(rightTreeIndex, source, middle + 1, right);
E treeData = merger.merge(elementData(leftTreeIndex), elementData(rightTreeIndex));
data[treeIndex] = new Node<>(treeData, left, right);
}
测试代码
public class Main {
public static void main(String[] args) {
Integer[] nums = {-2, 0, 3, -5, 2, -1};
SegmentTree<Integer> segmentTree = new SegmentTree<>(nums, Integer::sum);
System.out.println(segmentTree);
}
}
最后构造出的线段树如下,前面为元素值,括号中为包含的区间。
递归构造过程为
- 当左指针和右指针相等时,表示为叶子节点
- 将左孩子和右孩子值相加,构造当前节点,依次类推
2. 区间查询
/**
* 查询区间queryLeft-queryRight的值
*/
private E search(int treeIndex, int queryLeft, int queryRight) {
Node treeNode = data[treeIndex];
int left = treeNode.left;
int right = treeNode.rig