简介
树状树 是在线段树的基础上生成的,更精简,用在快速求 一串数据的区间和
code
public class BinaryIndexedTree {
private int[] tree;
private int n;
public BinaryIndexedTree(int [] arr) {
n = arr.length;
tree = new int[n+1];
buildTree(arr);
}
private void buildTree(int [] arr) {
for(int i = 0; i<n; i++) {
add(i+1, arr[i]);
}
}
private void add(int index, int value) {
while(index <= n) {
tree[index] += value;
index += index & (-index);
}
}
private int sum(int index) {
int sum = 0;
while(index > 0) {
sum += tree[index];
index -= index & (-index);
}
return sum;
}
public int rangeSum(int start, int end) {
return sum(end + 1) - sum(start);
}
}
技术难点
ndex & (-index) -- 获取数据最低位的1所在处 lowbit
1 & -1 = 1
2 & -2 = 2
3 & -3 = 1
4 & -4 = 4
[ 0, 0, 1, 2, 6, 4, 9, 6, 28, 8, 17, 10, 38, 12, 25, 14 ]
对于树状数组 生成的 数是这样的
第一个 0 无意义
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0(0), 1(0-1), 2(2), 6(0-3), 4(4), 9(4-5), 6(6), 28(0-7), 8(8), 17, 10, 38, 12, 25, 14
例如要求前9个数 即 0 -> 8的和
8
9 = 1001b
9 - lowbit(9) = 8
tree[8] = 28
8 + 28 = 36
8 = 1000b
8 - lowbit(8) = 0
最关键需要理解这一句话
序号为i的序列正好是长度为lowBit(i)且以i结尾的序列
---------------------------我的天空里没有太阳,总是黑夜,但并不暗,因为有东西代替了太阳。虽然没有太阳那么明亮,但对我来说已经足够。凭借着这份光,我便能把黑夜当成白天。我从来就没有太阳,所以不怕失去。
--------《白夜行》
浙公网安备 33010602011771号