mergesort实现中的合并方法包括不必要的右子数组副本?

时间:2013-06-06 17:46:50

标签: java algorithm sorting mergesort

我对合并排序算法中的合并方法有疑问。我从http://algs4.cs.princeton.edu/22mergesort/Merge.java.html复制了以下代码。我无法理解为什么我们需要复制正确的子数组。

本声明

if (i > mid) index[k] = aux[j++];

将右子数组复制到右子数组上。所以它基本上覆盖了相同的值。我觉得如果我已经越过中间那么

  1. 左子数组值已完全排序。
  2. 右子数组也排序到j。
  3. j(包括j)之后的所有条目已经排序,辅助数组和原始数组(a)具有相同的条目。
  4. 所以看起来如果我已经越过中间,我们可以取消复制到右边的子阵列声明。

    或许我错过了一个用例。如果你能搞清楚,请告诉我。

    // code begins
    
    private static void merge(Comparable[] a, int[] index, int[] aux, int lo, int mid, int hi) {
    
        // copy to aux[]
        for (int k = lo; k <= hi; k++) {
            aux[k] = index[k]; 
        }
    
        // merge back to a[]
        int i = lo, j = mid+1;
        for (int k = lo; k <= hi; k++) {
            if      (i > mid)                    index[k] = aux[j++];
            else if (j > hi)                     index[k] = aux[i++];
            else if (less(a[aux[j]], a[aux[i]])) index[k] = aux[j++];
            else                                 index[k] = aux[i++];
        }
    }
    

1 个答案:

答案 0 :(得分:1)

我相信你是对的 - 正如你所指出的那样,复制步骤似乎没必要。

这可能是旧版本合并函数的工件,其中要排序的两个数组未在输入数组中彼此相邻存储。如果输入数组存储在两个独立的数组中,则必须有一个最终的复制步骤,以便在另一个数组耗尽后将所有未使用的元素从一个数组移动到结果数组中。由于元素的存储方式存储在输入数组中,因此可能没有必要执行此步骤。

希望这有帮助!