Mergesort没有正确排序我的数组

时间:2015-10-05 22:42:05

标签: java arrays eclipse sorting

我试图对这个数组进行排序:

[5 1 3 2 2 9 1]

我已经运行了调试器并且得到了奇怪的结果。我在线上设置了一个断点

merge(left, right); 

在第一次传递后,这些是子数组:

left = [1 3 5 2 2]
right = [9]

所以我非常确定'划分'部分是我出错的地方。有人可以查看我的代码,看看他们是否能发现错误?

public int[] arrayToSort = { 5, 1, 3, 2, 2, 9, 1 };
...
private void mergeSort(int[] array, int low, int high) {
    // Base case
    if (!(high - low <= 1)) {
        int mid = low + (high - low) / 2;
        // Split array into sub-arrays
        int[] left = new int[mid];
        int[] right = new int[high - mid];
        // Fill sub-arrays
        for (int i = low; i < mid; i++) {
            left[i - low] = array[i];
        }
        for (int i = mid; i < high; i++) {
            right[i - mid] = array[i];
        }
        mergeSort(left, low, mid);
        mergeSort(right, mid + 1, high);
        merge(left, right);
    } else {
        return;
    }
}

private void merge(int[] left, int[] right) {
    int lLength = left.length;
    int rLength = right.length;
    // Pointer for left array
    int i = 0;
    // Pointer for right array
    int j = 0;
    // Pointer for merged array
    int k = 0;
    while (i < lLength && j < rLength) {
        if (left[i] < right[j]) {
            arrayToSort[k] = left[i];
            i++;
        } else {
            arrayToSort[k] = right[j];
            j++;
        }
        k++;
    }
    while (i < lLength) {
        arrayToSort[k] = left[i];
        i++;
        k++;
    }
    while (j < rLength) {
        arrayToSort[k] = right[j];
        j++;
        k++;
    }
}

感谢任何帮助!

编辑:注意到我的代码中的错误(参数未被使用)并对其进行了修改。这是我现在得到的错误(来自上面的代码):

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at Launcher.mergeSort(Launcher.java:43)
at Launcher.mergeSort(Launcher.java:49)
at Launcher.main(Launcher.java:21)

所以它在线上抱怨

left[i - low] = array[i];

2 个答案:

答案 0 :(得分:0)

你能发现这个片段中的问题吗? - &GT;

int mid = low + (high - low) / 2;
int[] left = new int[mid];
int[] right = new int[high - mid];
// ...
mergeSort(left, low, mid);
mergeSort(right, mid + 1, high);

leftright的大小以及传递给mergeSort的递归调用的索引怎么样?

您传递的索引是接收数组中的索引,而不是leftright中的索引。 当你看right时,问题最为明显。索引high将不可避免地总是超出范围。 以上会更有意义:

mergeSort(left, 0, left.length);
mergeSort(right, 0, high.length);

现在索引是正确的。它们也毫无意义,因为现在它们只是子阵列的全部范围,因此根本不需要。这种古怪只是一个更深层次问题的症状。

请记住merge最终必须更新原始数组。为此,它需要对原始数组的引用,以及左右范围。您正在传递合并左右子数组。在您的实现中将丢失对原始数组的引用和范围的索引。

考虑一下:

    int mid = low + (high - low) / 2;
    mergeSort(array, low, mid);
    mergeSort(array, mid + 1, high);
    merge(array, low, mid, high);

请注意:

  • 保留原始数组引用,因为它传递给递归调用
  • 索引是原始数组中的有效索引
  • 这里没有更多的子阵列

相应地更改merge的实现,以合并数组中指定的范围,修改该数组。一种简单的方法是将范围合并为大小为高 - 低的工作数组,然后从合并的工作数组复制回原始范围。

答案 1 :(得分:0)

只看代码,第二个递归调用应该是:

return new Blob([ia.buffer], {type:mimeString});

为左侧分配了比所需更多的空间:

    mergeSort(right, mid, high);

Merge()函数需要一个低参数来知道在哪里开始合并(k =低,而不是k = 0)。

我想知道为什么自下而上合并排序很少被教授,因为它更容易理解。