在实现递归冒泡排序时遇到堆栈溢出

时间:2013-02-12 18:32:01

标签: c++ visual-c++ recursion stack-overflow bubble-sort

嘿我将this C# code转换为c ++为

void bubbleSort(int *inputArray, int passStartIndex, int currentIndex,int length)
{
    if(passStartIndex == length - 1) return;
    if(currentIndex == length - 1) return bubbleSort(inputArray, passStartIndex+1, passStartIndex+1,length);

    //compare items at current index and current index + 1 and swap if required
    int nextIndex = currentIndex + 1;
    if(inputArray[currentIndex]>inputArray[nextIndex])
    {
        int temp = inputArray[nextIndex];
        inputArray[nextIndex] = inputArray[currentIndex];
        inputArray[currentIndex] = temp;
    }

    return bubbleSort(inputArray, passStartIndex, currentIndex + 1,length);
}

但是当我在长度为50100的输入数组上执行它时,它会显示我的expcetion

  

System.StackOverflowException未处理消息:未处理   example.exe中发生'System.StackOverflowException'类型的异常

我做错了什么?如何解决?

2 个答案:

答案 0 :(得分:3)

“我做错了什么?”

每次递归函数调用自身时,调用帧(激活记录)都存储在堆栈内存中。因此,当递归过深时,即达到堆栈最大大小的那一刻,执行就会终止。

另请参阅:Does C++ limit recursion depth?


“如何解决?”

如何避免此问题的最简单方法是永远不要将算法设计为递归。但是,一旦你已经有了这样的递归解决方案,在大多数情况下,可以将其重写为循环形式或(通常更容易):尾递归

基本上如果你能以一种永远不会直接将任何参数传递给下一个调用的方式重写你的函数,你就赢了。如果你查看你的递归,有2个点,它自己调用,在调用之前,只有currentIndexpassStartIndex被更改。想象一下,你会把这些索引存放在一边,当前的函数调用只会发出信号“我已经完成了,这些是有人应该继续的值:......现在你可以继续!”,表示不需要存储函数所在的状态。通过这样做,您最终会得到 Tail call (特别参见first example program)。

以下是有关如何使用您的代码完成示例的完整示例: Step 1 Step 2

答案 1 :(得分:3)

它不会解决您的问题(请参阅递归限制),但您使用的算法中存在错误。你应该替换

if (currentIndex == length - 1)
    return bubbleSort(inputArray, passStartIndex+1, passStartIndex+1, length);

通过

if (currentIndex == length - 1)
    return bubbleSort(inputArray, passStartIndex+1, 0,length - 1);

冒泡排序应重新开始为0,因为第一项不在正确的位置,但最后一项是。