为什么这个while循环比其他非常相似的while循环表现更差?

时间:2018-02-23 18:54:01

标签: algorithm sorting code-analysis insertion-sort

我正在尝试编写插入排序的变体。在我的算法中,当找到物品的正确位置时,不会发生值的交换。相反,它使用查找表(包含"链接"到主阵列中相应位置的较小值的数组)来查找项目的正确位置。当我们完成主数组中的所有n元素时,我们实际上并未更改主数组本身中的任何元素,但名为smaller的数组将包含指向即时的链接位置i, i+1, ... n中的较小值对应于主数组中的每个元素i, i+1, ... n。最后,我们遍历数组smaller,从主数组中存在最大值的索引开始,向后填充另一个空数组,最后得到排序序列。

刚刚描述的算法有点hacky / verbose实现:

public static int [] sort (int[] a) {
    int length = a.length;

    int sorted [] = new int [length];
    int smaller [] = new int [length];

    //debug helpers
    long e = 0, t = 0;

    int large = 0;
    smaller[large] = -1;

    here:
    for (int i = 1; i < length; i++) {

        if (a[i] > a[large]) {
            smaller[i] = large;
            large = i;
            continue;
        }

        int prevLarge = large;
        int temp = prevLarge;

        long st = System.currentTimeMillis();
        while (prevLarge > -1 && a[prevLarge] >= a[i]) {
            e++;
            if (smaller[prevLarge] == -1) {
                smaller[i] = -1;
                smaller[prevLarge] = i;
                continue here;
            }

            temp = prevLarge;
            prevLarge = smaller[prevLarge];
        }
        long et = System.currentTimeMillis();

        t += (et - st);

        smaller[i] = prevLarge;
        smaller[temp] = i;
    }

    for (int i = length - 1; i >= 0; i--) {
        sorted[i] = a[large];
        large = smaller[large];
    }

    App.print("DevSort while loop execution: " + (e));
    App.print("DevSort while loop time: " + (t));

    return sorted;
}

变量et包含执行内部while循环的次数以及执行while循环e次所花费的总时间。

以下是插入排序的修改版本:

public static int [] sort (int a[]) {
    int n = a.length;

    //debug helpers
    long e = 0, t = 0;

    for (int j = 1; j < n; j++) {
        int key = a[j];
        int i = j - 1;

        long st = System.currentTimeMillis();
        while ( (i > -1) && (a[i] >= key)) {
            e++;

            // simply crap
            if (1 == 1) {
                int x = 0;
                int y = 1;
                int z = 2;
            }

            a[i + 1] = a[i];
            i--;
        }
        long et = System.currentTimeMillis();

        t += (et - st);

        a[i+1] = key;
    }

    App.print("InsertSort while loop execution: " + (e));
    App.print("InsertSort while loop time: " + (t));

    return a;
}
引入while循环中的

if块只是为了匹配我的&#34; hacky&#34;的while循环内的语句数量。算法。请注意,修改后的插入排序中也引入了两个变量et

令人困惑的是,即使插入排序的while循环运行的次数与我的&#34; hacky&#34;中的while循环完全相同。对于我的算法,插入排序的算法t明显小于t

对于特定的运行,如果n = 10,000:

循环插入排序所需的总时间:20毫秒

我的算法在循环时所花费的总时间:98毫秒

如果n = 100,000;

循环插入排序所花费的总时间:1100毫秒

我的算法在循环时所花费的总时间:25251ms

实际上,因为条件1 == 1总是为真,所以while循环中的插入排序if块必须比我算法循环中的那个块更频繁地执行。有人可以解释一下发生了什么吗?

使用每种算法对包含相同顺序的相同元素的两个数组进行排序。

0 个答案:

没有答案