为什么我的选择排序比插入排序更快?

时间:2016-03-13 12:18:04

标签: java algorithm sorting

选择排序

__setattr__

插入排序

super().__setattr__

这是我的比较时间码。

public class Selection implements Sortable {
    public void sort(Comparable[] a){
        for(int i=0;i<a.length;i++){
            int min=i;
            for(int j=i+1;j<a.length;j++){
                if(less(a[j],a[min])){
                    min = j;
                }
            }
            exch(a,i,min);
        }
    }

    private boolean less(Comparable v,Comparable w){
        return v.compareTo(w) <0;
    }

    private void exch(Comparable[] a,int i,int j){
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

主要代码

public class Insertion implements Sortable{
    public void sort(Comparable[] a){

        for(int i=1;i<a.length;i++){
            for(int j=i;j>0;j--){
                if(less(a[j],a[j-1])){
                    exch(a,j,j-1);
                }
            }
        }

    }
}

结果让我感到惊讶。我已经运行了很多次。我的选择排序总是比插入排序快。我也多次检查我的代码。我不知道在哪里有问题。

public class SortCompare {

    public static double time(Sortable s,Comparable[] a){
        Stopwatch timer = new Stopwatch();
        s.sort(a);
        return timer.elapsedTime();
    }

    public static double timeRandomInput(Sortable s,int N,int T){
        double total = 0.0;
        Double[] a = new Double[N];
        for (int t=0;t<T;t++){
            for(int i=0;i<a.length;i++){
                a[i]= StdRandom.uniform()*10;  //get a random number
            }
            total+=time(s,a);
        }
        return total;
    }
}

如果我将数据集更改为10000.Selection alomost比Insertion快1倍。

public class Main {

    public static void main(String[] args) {
        Selection s = new Selection();
        Insertion i = new Insertion();
        //ShellSort sh =new ShellSort();
        double timeSelection = SortCompare.timeRandomInput(s,2000,100);
        double timeInsertion = SortCompare.timeRandomInput(i,2000,100);
        //double timeSh = SortCompare.timeRandomInput(sh,2000,100);
        System.out.println(timeSelection+" "+timeInsertion);
    }
}

我正在阅读这本书algorithm 4th。作者说,在一般情况下,插入排序将比选择排序更快。

3 个答案:

答案 0 :(得分:4)

也许是因为Insertion Sort的实现并没有那么好。它可以用&#34;大量的交换&#34;来编写,就像你一样。它通常在教科书中以这种形式出现,但在现实生活中却找不到 - 一个很好的实施方式将会移动到#34;元素(不交换它们)然后仅在该循环结束时将添加的元素戳到新打开的位置(而不是添加元素&#34;遍历&#34;数组)。这节省了大约一半的移动,并且重复访问数组以进行比较,以便每次都获得相同的项目(因此在Java中,还有许多边界检查)。

答案 1 :(得分:1)

理论上,插入排序和选择排序的渐近运行时间为O(n ^ 2)。

所以我不确定你为什么期望一个比另一个快。

此外,您正在测试的数据集非常小。如果你使用更大的数据集,我会期望运行时间相对增长更近。

答案 2 :(得分:0)

我在这里犯了一个愚蠢的错误。

只需更改以下代码即可。

public class Insertion implements Sortable{
    public void sort(Comparable[] a){

        for(int i=1;i<a.length;i++){
            for(int j=i;j>0;j--){
                if(less(a[j],a[j-1])){
                    exch(a,j,j-1);
                }
                else break;//i forget to add this line...
            }
        }

    }
}