什么是线段树
线段树是一种二叉搜索树,它将一个区间划分成一系列单元区间,每个单元区间对应线段树中的一个叶节点,见下图
上图中每个节点中的两个值形成一个区间,(start, end)二元组,
若一个节点的start!=end,说明该节点具有孩子节点,左孩子的区间为(start, (start+end)/2),右孩子的区间为 ((start+end)/2+1, end)
使用线段树可以快速的查找某一个索引或某个索引的区间,时间复杂度为O(logn),空间复杂度为O(n)
假设每个线段树的节点包含5个字段,start与end表示区间,left与right分别是左右孩子节点指针,value保存该节点维护的值
对于不同的问题,value可以存储不同含义的值,例如
1 区间最小数问题,value保存数组在该区间的最小数
2 区间求和问题,value保存数组在该区间的所有数之和
如何实现线段树
下面以区间求和问题为例,介绍线段树使用
问题描述如下:
实现两个方法 query(start, end) 和 modify(index, value):
对于 query(start, end), 返回数组中下标 start 到 end 的 和。
对于 modify(index, value), 修改数组中下标为 index 上的数为 value
样例
给定数组 A = [1,2,7,8,5]
query(0, 2), 返回 10
modify(0, 4), 将 A[0] 修改为 4
query(0, 1), 返回 6
modify(2, 1), 将 A[2] 修改为 1
query(2, 4), 返回 14
线段树节点Node
1 | class Node{ |
线段树SegmentTree
1 | class SegmentTree { |