【发布时间】:2015-08-05 00:57:22
【问题描述】:
如果我提供反向排序的数组,我的 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);
}
}
我的实现有问题吗?我该如何解决? 谢谢!
【问题讨论】:
-
如果列表是一个反向排序的数组,并且您总是选择最后一个元素作为枢轴,似乎预计您将获得大致长度的递归深度列表,因为您的分区之一将是空的。
-
来自Wikipedia,“分区的最左边的元素通常会被选为轴心......这会导致已经排序的数组出现最坏情况。”由于您使用最后一个作为枢轴和反向数组,因此这是最坏的情况。所以你真的没有一个好的实现,因为你将有 O(n^2)。您应该使用中间元素或其他元素作为枢轴。
-
谢谢你们俩。是的,我测试了最坏的情况,然后我得到了错误。现在我可以将其重写为迭代方法。
标签: java stack-overflow quicksort