Recursion 500个递归调用不是太多吗?

Recursion 500个递归调用不是太多吗?,recursion,stack-overflow,Recursion,Stack Overflow,协同性任务之一是找到二叉树的高度。该任务保证高度不超过500。所以想到的最简单的解决方案就是使用递归 现在,虽然这样一个解决方案通过了Codibility的所有测试,但我想知道我是否可以安全地假设500不是太多(对于任何可能成为Codibility测试平台的计算机/测试平台而言),或者我是否应该避免递归,或者模拟它,或者以其他方式找到树的高度 编辑:正如PM 77-1指出的,答案可能取决于我的递归是什么样子。所以我把它包括进去了。定义了一个struct: struct tree { int

协同性任务之一是找到二叉树的高度。该任务保证高度不超过500。所以想到的最简单的解决方案就是使用递归

现在,虽然这样一个解决方案通过了Codibility的所有测试,但我想知道我是否可以安全地假设500不是太多(对于任何可能成为Codibility测试平台的计算机/测试平台而言),或者我是否应该避免递归,或者模拟它,或者以其他方式找到树的高度

编辑:正如PM 77-1指出的,答案可能取决于我的递归是什么样子。所以我把它包括进去了。定义了一个
struct

struct tree {
  int x;
  tree * l;
  tree * r;
}; 
以下是我的解决方案:

int getHeight(tree const * T, int height)
{
    int maxHeight = height;
    if (T->l)
    {
        maxHeight = getHeight(T->l, height + 1);
    }
    if (T->r)
    {
        maxHeight = max(maxHeight, getHeight(T->r, height + 1));
    }
    return maxHeight;
}

int solution(tree * T)
{
    return getHeight(T, 0);
}
现在我的问题是-知道我的解决方案是什么样子(它可以使用多少内存/等等),而不知道测试平台的规格是什么,我可以安全地假设500个递归调用不会导致堆栈溢出吗?(因为如果是50或5,我认为我可以安全地假设,无论测试平台如何。)


编辑:我故意没有指定语言,因为Codibility支持多种语言,如果可能的话,我想得到一个关于不止一种语言的答案。但是,我在我的解决方案中使用C++,所以我想这是我最感兴趣的语言。

< P>这取决于许多因素,包括语言和每个调用使用的方法的堆栈空间。 对于Java,引用类型为8字节,默认堆栈大小通常为512 kB。一个方法至少需要1个引用(8字节)来存储返回地址,加上您声明的任何变量和参数(每个变量和参数可能都是8字节,因为您将使用的Java中的大多数变量都是引用或8字节整数)

让我们计算每个调用有多少堆栈空间可用。请注意,此计算忽略了程序其余部分所需的空间,并假设递归方法是堆栈中唯一的方法。我们还将假设该方法不调用自身以外的方法,因为很难说它们需要多少堆栈。实际上,您的工作空间会有所减少

(512000 bytes) / (500 calls) = 1024 bytes per call
(1024 bytes per call) / (8 bytes per reference) = 128 references per call

因此,对于500级递归,在耗尽堆栈空间之前,方法中可以有127个变量和参数(因为返回地址减去1)。即使有这些假设,你也不太可能达到这个极限。

你的问题太笼统了。并不是所有递归都相等。例如,如果您的递归在每次调用时都创建了一个非常大的对象,那么您可能会在
堆栈溢出
之前就从内存中取出
。没有人会说这对任何计算机/测试平台来说都不算太多。对于非常旧的计算机或嵌入式系统来说,这可能太过分了,但任何现代平台都应该毫无问题地处理它——也请阅读以下内容:简短的回答是不,你不能做出这样的假设。任何平台都是一个巨大的需求。想想智能咖啡机上内存最少的嵌入式Java,当然,你是对的,“任何平台”都太宽泛了。但我想的是“任何可能成为Codibility测试平台的平台”。这正是我想要的答案!然而,在接受之前,我将等待,看看其他人是否可以提供一些关于其他编程语言的信息。或者您可以?一些语言将进行优化,以减少递归方法调用的堆栈使用。对于每个方法调用,您找不到比Java消耗更多堆栈的语言,因为这几乎是通用行为。堆栈大小和引用大小也会有所不同。例如,如果您有一个32位的操作系统,一些语言,如C(但不是Java,因为它使用虚拟机)将有32位(4字节)的引用。在这种情况下,您可以在相同数量的堆栈空间上存储更多引用。在任何情况下都不能保证确切的堆栈空间是多少。