Algorithm 快速排序算法(Cormen)产生堆栈溢出

Algorithm 快速排序算法(Cormen)产生堆栈溢出,algorithm,stack-overflow,quicksort,Algorithm,Stack Overflow,Quicksort,我实现了快速排序算法,在算法简介(Cormen,第3版)7.1中给出了伪代码 当我尝试使用小数组的算法时,结果是正确的。但当我尝试使用N=50000时,数组已经像这样排序了; N={1,2,3,…,50000} 这给了StackOverflower错误。我认为这是因为函数本身递归了50000次。 快速排序(A,0,49999)=>快速排序(A,0,49998)=>快速排序(A,0,49997)。。。那就继续吧 我能解决这个问题吗?或者我应该使用不同的枢轴位置 这是我的密码 public void

我实现了快速排序算法,在算法简介(Cormen,第3版)7.1中给出了伪代码

当我尝试使用小数组的算法时,结果是正确的。但当我尝试使用N=50000时,数组已经像这样排序了; N={1,2,3,…,50000}

这给了StackOverflower错误。我认为这是因为函数本身递归了50000次。 快速排序(A,0,49999)=>快速排序(A,0,49998)=>快速排序(A,0,49997)。。。那就继续吧

我能解决这个问题吗?或者我应该使用不同的枢轴位置

这是我的密码

public void sort(int[] arr){ QuickSort(arr, 0, arr.length - 1); }

private void QuickSort(int[] A, int left, int right){
    if(left < right){
        int index = Partition(A, left, right);
        QuickSort(A, left, index - 1);
        QuickSort(A, index + 1, right);
    }
}

private int Partition(int[] A, int left, int right){
    int pivot = A[right];
    int wall = left-1;
    for(int i=left; i<right; i++){
        if(A[i] <= pivot){
            Swap(A, ++wall, i);
        }
    }
    Swap(A, wall + 1, right);
    return wall + 1;
}

private void Swap(int[] A, int x, int y){
    int keeper = A[x];
    A[x] = A[y];
    A[y] = keeper;
}
publicsvoidsort(int[]arr){QuickSort(arr,0,arr.length-1);}
私有void快速排序(int[]A,int左,int右){
if(左<右){
int index=分区(A,左,右);
快速排序(A,左,索引-1);
快速排序(A,索引+1,右);
}
}
私有int分区(int[]A,int左,int右){
int pivot=A[右];
内墙=左-1;

对于(int i=left;i是的,这个pivot方案不是排序数组的正确选择。正如您所注意到的,它会导致非常不平衡的分区,导致O(N^2)复杂性和非常深的递归级别。
有一些方法可以改善这种行为。 例如,您可以对pivot使用随机索引,例如
pivotIdx=start+rand()%(end-start+1);
,或者选择三种方法的中间值(索引范围中第一个、最后一个和中间元素的中间值)

另一个避免堆栈溢出的选项——首先对较短的段调用递归,然后对较长的段调用递归


那么这与我的代码无关,选择最后一个元素作为轴心是否是常见问题?是的,这是一个非常重要的问题。Cormen book展示了最简单的伪代码来解释主要的QS原理,我希望它稍后讨论这个问题(现在无法检查),我明白了,然后我将按照您的建议更改轴心。谢谢。