简单的递归跟踪理解堆栈

时间:2013-09-25 03:57:00

标签: c++ recursion tracing

我正在进行一项相当容易的追踪练习但是我并不完全理解为什么解决方案就是这样......

void f( int n) {
  if (n>0) {
    f(n-1)
     cout << n << " ";
  }
}

int main () {
  f(5);
  return 0;
}

答案是1 2 3 4 5,但是我想知道这是怎么回事,因为每次调用函数f它都不会到达cout线...我明白有一个堆叠系统最后看看实现的函数,但是直到它返回一个值乘以前一个n的阶乘示例,我不知道它是如何相似的。请不要再次使用factorial示例,我理解它,但我不是在这里如何实现cout ...感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

在递归调用f之后, 到达输出行。

这里重要的部分是停止条件

if (n>0)

这使得递归调用仅在n大于零时发生。并且由于递归调用是使用参数n - 1,它将会越来越低,直到它为零并且不再进行调用。

让我们为你追踪,因为你要懒惰在调试器(或纸上)自己做:

  1. 来自main的第一个电话。 n == 5并且明显大于零,因此使用5 - 1
  2. 进行递归调用
  3. 在第二个电话n == 4中,仍然大于零,因此再次使用4 - 1
  4. 进行通话
  5. 在第三个电话n == 3中,仍然大于零,因此再次使用3 - 1
  6. 进行通话
  7. 在第四个电话n == 2中,仍然大于零,因此再次使用2 - 1
  8. 进行通话
  9. 在第五个电话n == 1中,仍然大于零,因此再次使用1 - 1
  10. 进行通话
  11. 在第六个调用n == 0中,大于零,因此不再进行调用,函数返回。
  12. 返回n == 1,打印1,然后函数返回
  13. 返回n == 2,打印2,然后函数返回
  14. 返回n == 3,打印3,然后函数返回
  15. 返回n == 4,打印4,然后函数返回
  16. 返回n == 5,打印5,然后函数返回main函数
  17. 也就是说,如果编译它应该是如何工作的。现在它甚至都不会这么做,因为你会遇到编译器错误(代码如你的问题所示)。

答案 1 :(得分:0)

考虑调用f(1)的简单情况。我们通过if测试并对f(0)进行递归调用。此调用将返回不执行任何操作并继续执行f(1)的主体。下一个语句是对std::cout << 1 << " ";的调用:

// Substitute the parameter with the passed in argument n = 1
void f(1) {
  if (1 > 0) {
    f(0);
    std::cout << 1 << " ";
  }
}

您现在应该能够处理f(2)和一般f(n)的情况。每当你想到递归程序时,请考虑基本情况然后进行概括。通过用实际参数替换函数参数来编写代码。