【问题标题】:Recursion with code after the recursive call递归调用后的代码递归
【发布时间】:2018-08-13 17:46:40
【问题描述】:

我试图了解递归是如何工作的,但还有一件事我不太明白:当递归函数本身内的递归调用之后有代码时,递归函数是如何工作的.请参阅下面的示例伪代码以帮助了解我的意思。 我的确切问题是递归调用之后的代码将以什么顺序(意味着何时)执行。 机器会注意递归调用,在调用之后执行剩余的代码位(打印“完成”),然后返回并实际执行整个递归调用,或者机器将在到达该行时立即执行递归调用,并且仅在该递归底部之后执行最后一段代码(打印“完成”) out? 什么时候“完成”会被打印多少次?

void recurse()
{
  print "hello world";
  for i = 0 up to 2
    recurse();

  print "done";
}

【问题讨论】:

  • 当有递归调用时,编译器等不会对代码执行顺序的正常规则做出任何异常。事情的运行顺序与 recurse() 完全是其他函数一样。
  • 那么这意味着什么时候和多少次“完成”将被打印?请帮助我理解这一点!我是递归新手!
  • 由于本例中的递归是无限的,因此“完成”never 被打印出来。 (可能不是你想要的。)
  • @usercow 您是否尝试过使用任何语言?您的函数没有终止条件,这意味着它永远不会停止。对recurse() 的每次调用都会再调用两次,因此它打印"hello world" 的次数将呈指数增长,理论上是无限的。实际上,它最终会在"done"出现之前耗尽堆栈空间并崩溃。

标签: recursion


【解决方案1】:

递归调用在它下面的任何代码之前运行。一旦它返回,它将返回并完成其余的代码。那么会发生什么

"hello world"
i = 0
"hello world"
i = 0
"hello world"
...

永远。因为您没有将i 的值传递给下一个递归函数,所以您的代码将永远运行,每次都以i=0 重新启动。

假设您确实将i 正确传递给了递归函数:

void recurse(i) {
    // is i still < 2?
    if (i < 2) {
        print "hello world";
        recurse(i+1);
        print "done";
    }

recurse(0);

在这种情况下,你会得到:

i = 0
"hello world"
    i = 1
    "hello world"
        i = 2
    "done"
"done" 

【讨论】:

    【解决方案2】:

    可视化递归的一个好方法是使用堆栈的深度/高度。您可能知道,每当调用一个新函数时,它都会像煎饼一样被推入堆栈,将深度/高度增加 1。如果您对其进行编码并打印带有缩进的“开始”和“结束”注释以可视化深度,应该很容易看出什么时候执行的。如果不清楚,时间在 Y 轴上(上面打印的内容在下面的内容之前执行),递归深度在 X 轴上。

    这是 Python 中的代码:

    def recurse(depth=0):
        if depth < 4:
            print("    " * depth + f"starting at depth {depth}")
    
            for _ in range(2):
                recurse(depth + 1)
    
            print("    " * depth + f"ending at depth {depth}")
    
    recurse()
    

    输出:

    starting at depth 0
        starting at depth 1
            starting at depth 2
                starting at depth 3
                ending at depth 3
                starting at depth 3
                ending at depth 3
            ending at depth 2
            starting at depth 2
                starting at depth 3
                ending at depth 3
                starting at depth 3
                ending at depth 3
            ending at depth 2
        ending at depth 1
        starting at depth 1
            starting at depth 2
                starting at depth 3
                ending at depth 3
                starting at depth 3
                ending at depth 3
            ending at depth 2
            starting at depth 2
                starting at depth 3
                ending at depth 3
                starting at depth 3
                ending at depth 3
            ending at depth 2
        ending at depth 1
    ending at depth 0
    

    可以看出,循环中产生了两个相同的递归调用。通过循环的第一次行程在第二次开始之前完成其整个递归执行。两个递归调用完成后,整个调用结束。

    另请注意,深度表示没有子节点的base case 或终端/叶节点。您的原始算法将无限递归并炸毁堆栈。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-20
      • 1970-01-01
      • 1970-01-01
      • 2019-10-18
      • 2011-09-16
      • 2016-03-21
      • 1970-01-01
      相关资源
      最近更新 更多