问题描述
这是我的快速排序算法实现。尝试对大于15k元素的数组进行排序时,我收到System.StackOverflowException
并显示消息“引发了类型为'System.StackOverflowException'的异常”。。我实际上检查了15000、19000、20000、30000个元素,最后3个输入均抛出异常。
private static int ArraySplitter(int[] intArr,int low,int high)
{
int pivot = intArr[high];
int lowIndex = (low - 1);
for (int i = low; i < high; i++)
{
if (intArr[i] <= pivot)
{
lowIndex++;
int temp = intArr[lowIndex];
intArr[lowIndex] = intArr[i];
intArr[i] = temp;
}
}
int tempHigh = intArr[lowIndex + 1];
intArr[lowIndex + 1] = intArr[high];
intArr[high] = tempHigh;
return lowIndex + 1;
}
private static void QSort(int[] intArr,int high)
{
if (low < high)
{
int index = ArraySplitter(intArr,low,high);
QSort(intArr,index - 1);
QSort(intArr,index + 1,high);
}
}
public static void QuickSort(int[] intArr)
{
QSort(intArr,intArr.Length - 1);
}
我的python实现也破坏了具有大于5000个元素的数组。这是我的python代码-
def QUICKSORT(arr,p,r):
if p < r:
q = PARTITION(arr,r)
QUICKSORT(arr,q-1)
QUICKSORT(arr,q+1,r)
def PARTITION(arr,r):
x = arr[r]
i = p-1
for j in range(p,r-1):
if arr[j] <= x:
i = i + 1
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
temp = arr[i+1]
arr[i+1] = arr[r]
arr[r] = temp
return i+1
我遵循了Thomas H Cormen的算法简介中的伪代码。
似乎是问题所在,以及如何解决此问题?
解决方法
如果已对数据进行排序或反向排序,则选择子数组中的第一个或最后一个元素进行透视会导致最坏情况的空间复杂度O(n)。对于问题代码,在拆分以处理排序或反向排序的数据之前,将中间元素与最后一个元素(array [high])交换。仍然存在其他导致最坏情况行为的模式。
仅对较小的分区使用递归会将堆栈空间复杂度限制为O(log(n)),但最坏的情况下时间复杂度仍为O(n ^ 2)。
private static void QSort(int[] intArr,int low,int high)
{
while (low < high)
{
int index = ArraySplitter(intArr,low,high);
if((index - low) <= (high - index)){
QSort(intArr,index - 1);
low = index + 1;
} else {
QSort(intArr,index + 1,high);
high = index - 1;
}
}
}