快速排序算法(Cormen)给出了 ***

Posted

技术标签:

【中文标题】快速排序算法(Cormen)给出了 ***【英文标题】:Quicksort Algorithm (Cormen) gives *** 【发布时间】:2015-10-31 14:18:43 【问题描述】:

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

当我尝试使用小型数组的算法时,结果为真。但是当我尝试使用 N=50000 并且数组已经像这样排序时; N = 1, 2, 3, ..., 50000;

它给出了 ***Error。我认为它正在发生,因为函数自身递归了 50000 次。 QuickSort(A, 0, 49999) => QuickSort(A, 0, 49998) => QuickSort(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;

【问题讨论】:

【参考方案1】:

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

附:避免堆栈溢出的选项 - 首先为较短的段调用递归,然后为较长的段调用递归。

https://en.wikipedia.org/wiki/Quicksort#Choice_of_pivot

【讨论】:

那不是我的代码,选择最后一个元素作为pivot是不是很常见? 是的,这是一个非常重要的问题。 Cormen 的书展示了最简单的伪代码来解释主要的 QS 原理,我希望它以后讨论这个问题(现在不能检查) 我明白了,然后我会按照你的建议改变我的支点。谢谢。

以上是关于快速排序算法(Cormen)给出了 ***的主要内容,如果未能解决你的问题,请参考以下文章

C++中的快速排序

C++ 快速排序实现,没有正确的输出

如果快速排序算法中的第一个元素恰好是最小值怎么办

排序算法专题之快速排序

用C语言编程实现快速排序算法

快速排序实现 - Python