MergeSort递归中的java.lang.StackOverflowError

时间:2019-06-03 10:00:33

标签: java sorting

我尝试调试10个大小的列表。
ascendingSort(list, start, partition)运作良好。
但是递归ascendingSort(list, start, partition)之后,ascendingSort(list, partition, end)失败了,它的开始,结束不是5 10,而只是0 1。

public <T extends Comparable<T>> void ascendingSort(List<T> list) {
    ascendingSort(list, 0, list.size());
}

private <T extends Comparable<T>> void ascendingSort
        (List<T> list, int start, int end) {
    if (start == end) {
        return;
    }
    int partition = (start + end) >> 1;
    ascendingSort(list, start, partition);
    ascendingSort(list, partition, end);
    merge(list, start, partition, end);
}

private <T extends Comparable<T>> void merge
        (List<T> list, int start, int partition, int end) {
    List<T> leftList = new ArrayList<>();
    List<T> rightList = new ArrayList<>();
    Collections.copy(leftList, list.subList(start, partition));
    Collections.copy(rightList, list.subList(partition, end));
    int i = 0, j = 0;
    for (int k = start; k < end; k ++) {
        T leftElement = leftList.get(i);
        T rightElement = rightList.get(j);
        if (leftElement.compareTo(rightElement) > 0) {
            list.set(k, rightElement);
            j++;
        } else {
            list.set(k, leftElement);
            i++;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

代码中有一些问题:

if (start == end) {
    return;
}

不正确,您应该改用下一段代码:

if (end - start < 2) {
    return;
}

那是StackOverflowException的原因。尝试调试您的代码,看看它为什么会发生。

接下来,Collections.copy(leftList, list.subList(start, partition));不适用于空集合(leftList在创建时为空),我建议将子列表作为参数传递给构造函数:

List<T> leftList = new ArrayList<>(list.subList(start, partition));
List<T> rightList = new ArrayList<>(list.subList(partition, end));

此后,您将有一个例外IndexOutOfBoundException,因为在合并循环中不检查列表大小。请检查此link以获得数组的合并排序实现,并执行列表的实现。