多个递归调用

时间:2015-06-01 07:22:50

标签: c++ recursion time-complexity

我知道递归函数是什么以及我如何可视化堆栈顶部的每个递归调用。但我不知道如何在函数多次调用自身时如何思考

float foo(int n){

   int a = 0;
   for(int i = 0; i < n; i++)
       a += 1;

   if (n > 2)
       return foo(n/2) + foo(n/2); // What happens here?

    return a;
}

我现在想到两个不同的堆栈或者可视化结果的最佳方法是什么?

4 个答案:

答案 0 :(得分:2)

正如其他提到的答案,只有一个堆栈和递归调用严格按给定的顺序进行评估。

但是,出于分析目的,您可以将整个呼叫序列可视化为树。 Call tree for <code>foo(n)</code>

答案 1 :(得分:1)

return foo(n/2) + foo(n/2); // What happens here?

第一个表达式在第二个表达式评估之前完全评估。这与两个不同的堆栈无关。第一个调用的一个堆栈在计算时会扩展和收缩,一旦完全计算了这个表达式,第二个就会开始。

这有助于形象化吗?

答案 2 :(得分:1)

  

我现在想到两个不同的堆栈或者最好的方法是什么   可视化结果?

它仍然是一个堆栈。在这一行:

   return foo(n/2) + foo(n/2); // What happens here?

...将首先评估对foo()的一个调用(将其参数和局部变量推送到堆栈,使用,然后再次从堆栈中弹出),然后另一个将是以同样的方式评估。 (请注意,在语言规范中未定义首先评估foo()调用,因此由编译器的实现者来决定他们喜欢的顺序。

答案 3 :(得分:1)

让我们尝试为调用foo(4)的不同阶段可视化堆栈(是的,只有一个堆栈):

在调用foo(4)之前:调用者堆栈

在原始调用foo(4)中:stack = 调用者堆栈,foo(4)

当foo(4)在第一次调用foo(2)时:调用者堆栈,foo(4),foo(2)

foo(4)在foo(2)的第一次调用中,其中foo(2)已经调用了第一个foo(1):调用者堆栈,foo(4),foo(2),foo( 1)

从第一个foo(1)返回后

:再次调用者堆栈,foo(4),foo(2)

foo(4)在foo(2)的第一次调用中,其中foo(2)调用了第二个foo(1):调用者堆栈,foo(4),foo(2),foo(1) )

从第二个foo(1)返回后:再次调用者堆栈,foo(4),foo(2)

从第一个foo(2)返回后

来电堆栈,foo(4)

foo(4)在第二次调用foo(2)之内:调用者堆栈,foo(4),foo(2)

foo(4)在foo(2)的第二次调用中,其中foo(2)已经调用了第一个foo(1):调用者堆栈,foo(4),foo(2),foo( 1)

从第一个foo(1)返回后

:再次调用者堆栈,foo(4),foo(2)

foo(4)在foo(2)的第二次调用中,其中foo(2)调用了第二个foo(1):调用者堆栈,foo(4),foo(2),foo(1) )

从第二个foo(1)返回后:再次调用者堆栈,foo(4),foo(2)

从第二个foo(2)返回后

来电堆栈,foo(4)

从foo(4)返回后

来电堆栈