線段樹這種數據結構可讓統計更快,好比任何多數據求和操做能夠在LOG(N)的複雜度完成。數組
public class SegmentTree<E> {
private E[] data;
private E[] tree;
private Marger<E> marger;
public SegmentTree(E[] arr, Marger<E> marger) {
data=(E[]) new Object[arr.length];
this.marger = marger;
for (int i = 0; i < arr.length; i++) {
E e=arr[i];
data[i]=e;
}
tree= (E[]) new Object[4*arr.length];
buildSegmentTree(0,0,data.length-1);
}
//zai treeindex位置,建立表示區間【l,r】的線段樹
private void buildSegmentTree(int treeIndex, int l, int r) {
if (l==r){
tree[treeIndex]=data[l];
return;
}
int leftindex=leftChild(treeIndex);
int rightindex=rightChild(treeIndex);
int mid=l+(r-l)/2;
buildSegmentTree(leftindex,l,mid);
buildSegmentTree(rightindex,mid+1,r);
tree[treeIndex]= marger.marger(tree[leftindex],tree[rightindex]);
}
public int getSize(){
return data.length;
}
public E get(int index){
if (index<0||index>=data.length)
throw new IllegalArgumentException("index fail");
return data[index];
}
private int leftChild(int index){
return 2*index+1;
}
private int rightChild(int index){
return 2*index+2;
}
public String toString(){
StringBuilder res = new StringBuilder();
for (int i = 0; i < tree.length; i++) {
if (tree[i]!=null)
res.append(tree[i]);
else res.append("null");
res.append("+");
}
return res.toString();
}
public static void main(String[] args) {
Integer[] nums={-2,0,3,-5,2,-1};
SegmentTree<Integer> segmentTree=new SegmentTree<Integer>(nums, (a,b)->a+b);
System.out.println(segmentTree.toString());
}
}複製代碼