我相信Java TreeSet有一个平衡的树实现,可以快速执行树类排序(很像快速排序)。我最近遇到的问题表明它似乎正在进行我期望的更多比较。
每个平衡树在排序(插入)上是否像Java的TreeSet一样,或者我的性能测试方法是否错误?
我的代码:
package expri.johnny.treeSortCompTimes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetCompTimeTest {
public static void main(String[] args) {
int size=1000;
ArrayList<Integer> ay =new ArrayList<>(size);
int treeHeight = (int) (Math.log (size)/Math.log (2));
System.out.println("tree height: "+treeHeight);
System.out.println("when size is "+ size + ",i expected compare tmies are: "+((treeHeight+1)*treeHeight/2));
for(int i =0,l=size-1;i<=l;i++){
ay.add(i);
}
Collections.shuffle(ay);
System.out.println(ay);
CountComp cc =new CountComp();
TreeSet<Integer> ts =new TreeSet<>(cc);
ts.addAll(ay);
cc.speakCount();
}
private static class CountComp implements Comparator<Integer>{
int counter =0;
@Override
public int compare(Integer o1, Integer o2) {
this.counter++;
int df = o1-o2;
if(df>0){
return 1;
}else if(df==0){
return 0;
}else{
return -1;
}
}
public void speakCount(){
System.out.println("total compared times: "+this.counter);
//when size is 100,i expected compare tmies are: 21
//total compared times: 545
//when size is 1000,i expected compare tmies are: 45
//however, the real total compared times: 8783
}
}
}
嗯,这就是我之前的想法:
10 compares for add
10 compares for add
10 compares for add
10 compares for add
10 compares for add
10 ...
10
10
10
10
10
10 -997th , what i thought was 7
10 -998th , what i thought was 8
10 - 999th , what i thought was 9
10 - 1000th , what i thought was 10
8547
这次我笑了很多,哈哈哈!
答案 0 :(得分:1)
当假设插入将使用log(n)
比较时,您是正确的。
但是您插入了n
元素,这些元素可以让我们进行n*log(n)
比较。
对于1000个元素,它给我们9965比较。
n
这里是元素的总数。
你的公式完全错了,我不知道你在哪里得到它。
答案 1 :(得分:1)
随着项目的添加,树的深度是动态的。要估计将要进行的比较次数,迭代要添加的元素的大小,并根据当时树的大小计算每个元素的比较次数。
int sum = 0;
for(int i = 1; i <= size; i++){
sum += (int)Math.ceil(Math.log(i)/Math.log(2));
}
System.out.println(sum);
为1000个元素产生8987
。