线段树(Segment Tree)是一种可以对区间进行快速查询与快速更新的数据结构。
线段树有两个操作:
1 void update(int i, int delta):更新数组中下标为i的元素的值,将其值加delta
2 int get(int min, int max):得到区间[min, max]和
时间复杂度:更新和求区间和操作都是
空间复杂度:
线段树与树状数组非常相似,都是在长度为n的数组中,以O(log n)的时间复杂度更新数组元素,以O(log n)的时间复杂度得到区间和/前缀和。
java代码实现:
/**
* 0
* / \
* 1 2
* / \ / \
* 3 4 5 6
* / \ / \ / \ / \
* 7 8 9 10 11 12 13 14
*/
public class SegmentTree {
private int[] nodes;
private int size;
public SegmentTree(int size) {
this.size = size;
nodes = new int[size * 4];
}
public void update(int i, int delta) {
update(i, delta, 0, 0, size - 1);
}
private void update(int i, int delta, int ni, int left, int right) {
if (left > i || right < i) return;
nodes[ni] += delta;
if (left < right) {
int middle = (left + right) / 2;
update(i, delta, ni * 2 + 1, left, middle);
update(i, delta, ni * 2 + 2, middle + 1, right);
}
}
public int get(int i) {
return get(i, i);
}
public int get(int min, int max) {
return get(min, max, 0, 0, size - 1);
}
private int get(int min, int max, int ni, int left, int right) {
if (left >= min && right <= max) {
return nodes[ni];
} else if (right < min || left > max) {
return 0;
} else { // left < right
int middle = (left + right) / 2;
return get(min, max, ni * 2 + 1, left, middle) +
get(min, max, ni * 2 + 2, middle + 1, right);
}
}
}
源代码地址:https://github.com/SSSxCCC/Algorithm
接下来推荐看线段树的升级版:zkw线段树