大输入上的QuickSort堆栈溢出

时间:2015-05-22 21:37:29

标签: java stack-overflow quicksort

如果我提供反向排序的数组,我的QuickSort实现会导致StackOverflow错误。它适用于大约1000项,但对于10000+我得到StackOverflow错误。如果我得到错误,递归深度约为9000.我知道我的算法总是选择子阵列的最新元素作为枢轴,这不是最优的,但我不会改变它,因为我想让它像这样工作。 这是代码:

private int partition(int[] numbers, int begin, int end) {
    int pivot = numbers[end];
    int partitionIndex = begin;
    for (int i = begin; i < end; ++i) {
        comparisonCounter++;
        if (numbers[i] <= pivot) {
            if (i != partitionIndex) {
                swapCounter++;
                int temp = numbers[i];
                numbers[i] = numbers[partitionIndex];
                numbers[partitionIndex] = temp;
            }
            partitionIndex++;
        }
    }
    if (partitionIndex != end) {
        swapCounter++;
        int temp = numbers[partitionIndex];
        numbers[partitionIndex] = numbers[end];
        numbers[end] = temp;
    }
    return partitionIndex;
}

private void quickSort(int[] numbers, int begin, int end) {
    if (begin < end) {
        int partitionIndex = partition(numbers, begin, end);
        quickSort(numbers, begin, partitionIndex - 1);
        quickSort(numbers, partitionIndex + 1, end);
    }
}

我的实施有问题吗?我该怎么办呢? 谢谢!

2 个答案:

答案 0 :(得分:0)

您的代码似乎没有任何问题,但请记住,这是一个递归函数,并且大多数语言都有一个有限深度的堆栈,如果您有足够大的输入,您必须得到它。对于Java,请参阅:

您可以做的是将您的方法从递归方法转变为迭代方法。有几种方法可以做到。我刚刚在网上找到了几个例子:

答案 1 :(得分:0)

有一些方法可以减少Quicksort中的堆栈大小。

  • 您可以每次将较大的分区放在堆栈上,而将较小的分区排在第一位。这使得太多的小分区不会立刻堵塞堆栈。

  • 您可以使用其他方法(例如插入排序)对小分区而不是Quicksort进行排序。同样,这使得很多小分区从堆栈中移除。你可以进行实验,但是15-20个元素区域的东西通常算作一个小小的&#34;分区。

正如你所说,使用更好的方法来挑选你的支点也会有所帮助。

相关问题