【发布时间】:2017-06-13 08:56:24
【问题描述】:
我正在编写一个二叉索引树。作为文档,它需要 nlogn 时间进行预处理。但我无法理解为什么。
在我的情况下,我从数组构造树,这应该花费 2n 时间,因为第一次遍历数组一次以使其成为二叉树,然后更新总和,我再次以 POST 顺序遍历树。所以总共2n,而不是nlogn。
谁能解释为什么它需要 nlogn 时间来预处理二叉索引树。
public class BITree {
private class BTN {
int data;
int index;
BTN left,right;
public BTN(int data) {
this.data = data;
}
}
BTN head = null;
public BTN toBT(int[] arr,int start,int end){
if(start <= end){
int mid = start + (end - start)/2;
BTN btn = new BTN(arr[mid]);
btn.index = mid+1;
btn.left = toBT(arr,start,mid-1);
btn.right = toBT(arr,mid+1,end);
return btn;
}
return null;
}
public int sumAtIndex(BTN btn,int index){
int sum = 0;
if(index < btn.index)
sum += sumAtIndex(btn.left,index);
else if(index > btn.index) {
sum += btn.data + sumAtIndex(btn.right, index);
}
if(btn.index == index)
return btn.data + sum;
return sum;
}
public int replaceSum(BTN btn){
if(btn == null){
return 0;
}
int l = replaceSum(btn.left);
int r = replaceSum(btn.right);
int sum = btn.data + l + r;
btn.data += l;
return sum;
}
void inOrder(BTN btn){
if(btn != null) {
inOrder(btn.left);
System.out.print((btn.index+":"+btn.data)+",");
inOrder(btn.right);
}
}
public static void main(String[] args) {
int[] arr = {5,1,6,4,2,3,3};
BITree s2 = new BITree();
BTN btn = s2.toBT(arr,0,arr.length-1);
s2.replaceSum(btn);
s2.inOrder(btn);
System.out.println();
System.out.println(s2.sumAtIndex(btn,3));
}
}
【问题讨论】:
-
这不是
Binary Indexed Tree(Fenwick tree)。这是一个简单的BST,做了一些修改。对于Binary Indexed Tree,请查看here。 -
@RBanerjee 当我学习这个时,我提到了这个tutorial。它写得很好,它肯定会消除你的疑虑,即它与简单的
Binary Tree有何不同。 -
@SanketMakani 查看维基百科上的谈话标签:stackoverflow.com/questions/31068521/…
-
@Thilo,非常感谢。你消除了我的疑虑,我学到了一个有趣的方法。 :)