快速排序-最坏的情况会导致堆栈溢出

Quicksort - Worst case results in stack overflow?

本文关键字:堆栈 栈溢出 情况 最坏 快速排序      更新时间:2023-10-16

我正在尝试实现快速排序算法,其中我选择pivot作为最右边的元素。。但是,当约4000个元素的数组已经排序时,就会发生堆栈溢出。这是我的实现:

void quickSortSimpleAscending(int elements[], int startindex, int endindex)
{
    int pivot = elements[endindex];
    int i = startindex;
    int j = endindex;

    while (i < j)
    {
        while (elements[i] < pivot)
            i++;
        while (elements[j] > pivot)
            j--;

        if (i <= j)
        {
            swap(elements[i], elements[j]);
            i++;
            j--;
        }
    }

    if (startindex < j)
        quickSortSimpleAscending(elements, startindex, j);

    if (i < endindex)
        quickSortSimpleAscending(elements, i, endindex);
}

如果不使用"三的中位数"方法,有没有办法解决这个问题?谢谢

首先,很高兴看到您的代码没有使用三的中值来选择枢轴。您只需选择元素向右旋转即可。

如果不使用"三的中位数"方法,有没有办法解决这个问题?

三的中位数本身并不是堆栈溢出的原因。当通过连续和递归调用获得坏分区时,可能会发生溢出;也就是说,当枢轴导致左分区比右分区大得多时。在您的具体案例中,如果数组已经排序,那么您将获得n - 1元素的左分区和零大小的右分区。下一次你会得到一个n - 2的左分区,依此类推。所以算法会执行n递归调用,对于适度的堆栈大小,它会溢出。

解决方案

为了降低溢出的风险,并在实践中避免溢出,解决方案是首先对最小的分区进行排序。使用这种方法,当您获得最佳分区时,最坏的情况将发生;也就是说,当它们的大小趋于相等时。在这种情况下,连续递归调用的最大数量为log(n)

我希望这将对有帮助

事实上,如果不限制递归的深度,迟早会出现堆栈溢出。一种常见的解决方法是在函数中添加第四个参数以跟踪深度,并在达到一定限制时切换到其他排序算法。