Quicksort - 最坏情况导致堆栈溢出?

时间:2015-11-19 22:09:24

标签: c++ stack-overflow quicksort

我正在尝试实现快速排序算法,我选择枢轴作为最右边的元素。但是,当已经对~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);
}

有没有办法解决这个问题而不使用“三个中位数”的方法? 谢谢!

2 个答案:

答案 0 :(得分:2)

首先,很高兴看到您的代码不使用三个中间值来选择枢轴。您只需选择右侧元素作为枢轴。

  

有没有办法解决这个问题而不使用方法&#34;三个中位数&#34;?

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

解决方案

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

我希望这会有所帮助

答案 1 :(得分:0)

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