Java 具有 20,000 个或更多整数的快速排序堆栈溢出

Java QuickSort Stack Overflow with 20,000 or more integers

当我对包含 20,000 个或更多整数的数组进行 运行 快速排序时,出现以下错误。

线程异常 "main" java.lang.WhosebugError 在项目 1.Project1.quickSort(Project1.java:31)

我用 p=0 和 r=array.length-1

调用快速排序
public static int[] createArray(int size)
{
    int []array = new int[size];
    for(int i=0;i<size;i++)
    {
        array[i]= randomGenerator.nextInt(100000);
    }
    return array;
}
public static void quickSort(int p, int r)
{
    if(p < r)
    {
        int q = partition(p, r);
        quickSort(p,q - 1);
        quickSort(q+1,r);
    }
}

public static int partition(int p,int r)
{
    int x = array[r];
    int i = p-1;
    for(int j=p;j<=r-1;j++)
    {
        if(array[j]<= x)
        {
            i++;
            swap(i,j);
        }
    }
    swap(i+1,r);
    return i+1;
}

public static void swap(int i, int j)
{
    int temp = array[i];
    array[i]= array[j];
    array[j]= temp;
}

public static void main(String[] args) 
{
    //Get all the required input data
    System.out.print("Size to be tested: ");
    sc = new Scanner(System.in);
    int input = sc.nextInt();
    float selectionAvg= 0,quickAvg= 0,countAvg=0, medianAvg=0;

    //Run the Quick sort algorithm
    array= startArray;
    int low= 0;
    int high = array.length-1;
    startTime= System.currentTimeMillis();
    quickSort(low, high);
    endTime = System.currentTimeMillis();
    time= endTime - startTime;
    System.out.println("Quick Sort Time: " + time + " milliseconds");  
    //printArray();
    quickAvg+= time;
}

您可以考虑将您的程序修改为可迭代的。这样做的基本思路是自己用一个栈来处理当前递归处理的工作。

阅读此 article 以进一步参考。

简单实施 QuickSort 的问题之一是递归深度在最坏情况下为 O(n)。如果所有或几乎所有分区仅将 O(1) 元素分配给结果分区之一,就会发生这种情况。将触发的条件取决于枢轴的选择和数据。在您的特定情况下,如果数组元素都具有相同的值或者它们是排序的或反向排序的,那么看起来会发生这种情况。这种情况可能解释了您的堆栈溢出。

枢轴的选择对于快速排序非常重要,它可以高效地处理最广泛的输入。我建议将三分中位数或随机选择作为相当不错、相对简单的选择。这些中的任何一个都可以解决[反向]排序的情况,但需要进行额外的更改才能解决常量值的情况。

此外,您可以确定将递归深度限制为最多O(log n),方法是仅对每个分区的较小部分进行递归排序,而不是循环对较大的部分。这很难通过在递归调用的单独函数中执行的分区来实现,但它 相当好地解决常量值的情况。