【问题标题】:Encountering stack overflow while implementing recursive Bubble sort在实现递归冒泡排序时遇到堆栈溢出
【发布时间】:2013-01-28 03:48:34
【问题描述】:

嘿,我将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 的输入数组上执行它时,它显示了我的异常

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

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

【问题讨论】:

  • 我也看到了@Benoit 发现的错误,但我仍然不明白为什么递归没有终止。 passStartIndex 的测试似乎相当可靠。顺便说一句,我在我的 Linux 机器上运行这段代码时遇到了分段错误,而不是堆栈溢出,尽管这可能意味着同样的事情。但是,当长度为 510 而不是 50100 时,失败发生在我身上。我认为堆栈正在以某种方式被破坏,而不是无限递归。不幸的是,我没有更多的时间来做这件事了。祝你好运。

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


【解决方案1】:

“我做错了什么?”

递归函数每次调用自身,调用帧(激活记录)被存储到栈内存中。所以当递归变得太深时,也就是你达到堆栈的最大大小的那一刻,执行就会终止。

也可以看看:Does C++ limit recursion depth?


“如何解决?”

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

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

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

【讨论】:

    【解决方案2】:

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

    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,因为第一项不在正确的位置,但最后一项是。

    【讨论】:

      猜你喜欢
      • 2012-05-28
      • 1970-01-01
      • 2013-10-09
      • 2016-11-14
      • 2021-06-22
      • 2013-12-02
      • 2015-04-04
      • 2017-01-20
      • 2018-12-02
      相关资源
      最近更新 更多