递归合并排序中的超出界限异常

时间:2014-10-18 18:26:02

标签: sorting indexoutofboundsexception mergesort

我想知道是否有人可以帮我弄清楚为什么我在这段代码中有一个Out of Bounds异常。我尝试了一切。 Eclipse说它发生在mergeSortRecursive和merge调用。 谢谢!

// Wrapper方法

public static <E extends Comparable <E>> void mergeSort (E[]list){
    mergeSortRecursive(list, 0, list.length-1);
}

// mergeSort递归,它接受一个左指针和右指针,包装类表示为0和list.length -1

private static <E extends Comparable<E>> void mergeSortRecursive(E[] list, int left,
        int right) {
    // Base case
    if (left == right) {
        return;
    }
    int mid = left + right / 2;
    mergeSortRecursive(list, left, mid);
    mergeSortRecursive(list, mid + 1, right);
    merge(list, left, mid, mid + 1, right);

}

//合并两个列表

public static <E extends Comparable<E>> void merge(E[] list, int leftFirst,
        int leftLast, int rightFirst, int rightLast) {
    @SuppressWarnings("unchecked")
    E[] mergeList = (E[]) Array.newInstance(list.getClass()
            .getComponentType(), rightLast - leftFirst + 1);
    int rightIndex = rightFirst;
    int leftIndex = leftFirst;
    int index = 0;

    while (leftIndex < leftLast && rightIndex < rightLast) {
        if (list[leftIndex].compareTo(list[rightIndex]) < 0) {
            mergeList[index] = list[leftIndex];
            leftIndex++;

        } else {
            mergeList[index] = list[rightIndex];
            rightIndex++;

        }
        index++;
    }
    while (leftIndex < leftLast) {
        mergeList[index] = list[leftIndex];
        index++;
        leftIndex++;
    }
    while (rightIndex < rightLast) {
        mergeList[index] = list[rightIndex];
        index++;
        rightIndex++;
    }
    for (int i = 0; i < list.length; i++) {
        list[i] = mergeList[i];
    }
}

1 个答案:

答案 0 :(得分:0)

我查看了你的代码并认为我已经解决了错误。看起来有很多独立的问题共同导致程序无法正常工作。

首先,一个小问题:这是您进行递归调用的代码:

int mid = left + right / 2;
mergeSortRecursive(list, left, mid);
mergeSortRecursive(list, mid + 1, right);
merge(list, left, mid, mid + 1, right);

声明mid的行中的运算符优先级与您的预期略有不同。我想你打算写

int mid = (left + right) / 2;

实际上找到了两个元素的平均值。

你得到的IndexOutOfBoundsException是由于这些行所在:

for (int i = 0; i < list.length; i++) {
    list[i] = mergeList[i];
}

这里的问题是list是整个列表,而不仅仅是您尝试与此特定调用合并的部分。要解决此问题,您可以像这样重写它:

    for (int i = 0; i < mergeList.length; i++) {
        list[i + leftFirst] = mergeList[i];
    }

这只会复制您合并到外部合并数组中的数组部分。

如果您进行了这些更改,您将开始获得一些奇怪的NullPointerException。问题是您将范围的左端点和右端点视为包含边界,但您的合并算法将它们视为排除边界。您可以通过更改while循环的条件来解决此问题:

while (leftIndex <= leftLast && rightIndex <= rightLast) {
    if (list[leftIndex].compareTo(list[rightIndex]) < 0) {
        mergeList[index] = list[leftIndex];
        leftIndex++;

    } else {
        mergeList[index] = list[rightIndex];
        rightIndex++;

    }
    index++;
}
while (leftIndex <= leftLast) {
    mergeList[index] = list[leftIndex];
    index++;
    leftIndex++;
}
while (rightIndex <= rightLast) {
    mergeList[index] = list[rightIndex];
    index++;
    rightIndex++;
}

随着这些变化,一切似乎都有效!