该代码源自b站视频,本人只稍作修改!
【数据结构】线段树(Segment Tree)
考虑到存储线段树数组的空间大小问题,所以写了个len的计算公式,具体表现便是2的k+1次幂减1。可以以数组大小为6的数组作为样例,做出其二叉树(如视频所示),然后将其完全二叉树转换为满二叉树即可(由于本人实力有限,无法给出数学证明,所以公式有可能有误,还请多多指教)。读者也可尝试多种样例证明,如果仍遇到数组溢出问题请及时提出并指正!感谢!
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int arr[]=new int[100000];
Arrays.fill(arr,1);
final int len = (int) Math.pow(2,Log(2,2*arr.length-1)+1)-1;
System.out.println("len:"+len);
int tree[] = new int [len];
int sum = 0;
build_tree(arr,tree,0,0,arr.length-1);
System.out.println(Arrays.toString(tree));
for (int i: arr){
sum += i ;
}
System.out.println(sum);
}
private static int Log(int base,int value){
return (int) (Math.log(value)/Math.log(base));
}
private static void build_tree(int arr[],int tree[],int node,int start,int end){
if (start == end) {
tree[node] = arr[start];
}
else {
int mid = (start + end) / 2;
int left_node = node * 2 + 1;
int right_node = node * 2 + 2;
build_tree(arr, tree, left_node, start, mid);
build_tree(arr, tree, right_node, mid + 1, end);
tree[node] = tree[left_node] + tree[right_node];
}
}
}
可见存储空间比起固定长度要节约不少