在C#中使用递归

Ted*_*ith 16 c# stack-overflow recursion

在使用递归来避免堆栈溢出时是否有任何一般规则?

Jon*_*eet 32

你可以多少次递归取决于:

  • 堆栈大小(通常为1MB IIRC,但二进制文件可以手工编辑;我不建议这样做)
  • 递归的每个级别使用多少堆栈(例如,具有10个未捕获的Guid局部变量的方法将比不具有任何局部变量的方法占用更多堆栈)
  • 您正在使用的JIT - 有时JIT 使用尾递归,有时则不会.规则很复杂,我不记得了.(有一个博客文章由大卫Broman从2007年回来,并从同一作者/日期的MSDN页面,但他们可能会过时的现在.)

如何避免堆栈溢出?不要过分递归:)如果你不能合理地确定你的递归会在没有走得很远的情况下终止(我会担心"超过10"虽然这是非常安全的)然后重写它以避免递归.


Mic*_*ows 8

这实际上取决于你正在使用的递归算法.如果它是简单的递归,你可以这样做:

public int CalculateSomethingRecursively(int someNumber)
{
    return doSomethingRecursively(someNumber, 0);
}

private int doSomethingRecursively(int someNumber, int level)
{
    if (level >= MAX_LEVEL || !shouldKeepCalculating(someNumber))
        return someNumber;
    return doSomethingRecursively(someNumber, level + 1);
}
Run Code Online (Sandbox Code Playgroud)

值得注意的是,这种方法仅在将递归级别定义为逻辑限制时才有用.如果不能发生这种情况(例如分而治之算法),则必须决定如何平衡简单性与性能与资源限制之间的关系.在这些情况下,一旦达到arbritrary预定义的限制,您可能必须在方法之间切换.我在快速排序算法中使用的有效方法是将其作为列表总大小的比例.在这种情况下,逻辑限制是条件不再是最佳时的结果.


bat*_*rat 7

我不知道有任何难以避免的堆栈溢出.我个人试图确保 -
1.我的基本情况是正确的.
2.代码在某些时候到达基本情况.