如果我提供反向排序的数组,我的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);
}
}
我的实施有问题吗?我该怎么办呢? 谢谢!
答案 0 :(得分:0)
您的代码似乎没有任何问题,但请记住,这是一个递归函数,并且大多数语言都有一个有限深度的堆栈,如果您有足够大的输入,您必须得到它。对于Java,请参阅:
您可以做的是将您的方法从递归方法转变为迭代方法。有几种方法可以做到。我刚刚在网上找到了几个例子:
答案 1 :(得分:0)
有一些方法可以减少Quicksort中的堆栈大小。
您可以每次将较大的分区放在堆栈上,而将较小的分区排在第一位。这使得太多的小分区不会立刻堵塞堆栈。
您可以使用其他方法(例如插入排序)对小分区而不是Quicksort进行排序。同样,这使得很多小分区从堆栈中移除。你可以进行实验,但是15-20个元素区域的东西通常算作一个小小的&#34;分区。
正如你所说,使用更好的方法来挑选你的支点也会有所帮助。