有人可以直观地向我解释此代码吗?

时间:2019-09-12 09:40:15

标签: algorithm recursion

我了解递归及其对有效编写代码的好处。虽然我可以编写递归函数的代码,但似乎无法将其工作原理全神贯注。我希望有人能本能地解释我的递归。

例如,此代码:

int fact(int n)
    { if n<0:
        return -1
      elif n==0:
        return 1
      else
        return n*fact(n-1)
    }

这些是我的一些问题:

  1. 假设n = 5。在输入函数时,由于没有一个先前的条件被满足,因此控制转到最后一个return语句。 现在,大致上,计算机“写入”如下内容:5 *(fact(4)) 再次,fact()函数被调用,并且相同的过程被重复,除了现在我们有n = 4。 因此,编译器如何精确地将5 * 4乘以2直到2,因为它不是完全5 * 4而是5 * fact(4)。

  2. ,如何“记住”必须将两个整数相乘以及将临时值存储在哪里呢?

  3. 再次假设n = 5。相同的过程继续进行,最终n递减为0。我的问题是,为什么/为什么函数不像return语句中那样简单地返回1。与我之前的问题类似,编译器如何“记住”它还存储了180个供显示?

如果有人向我完全解释这一点,以便能够更好,更直观地理解递归,我将非常感谢。

2 个答案:

答案 0 :(得分:2)

是的,对于初学者而言,递归可能会造成混乱。但是,您已经在正确的轨道上,在“ 1”下进行了解释。

该函数将递归调用,直到满足中断条件为止。在这种情况下,当n等于0时满足中断条件。此时,将不再进行递归调用。每次递归调用的结果都将返回给调用者。呼叫者总是“等待”直到获得结果。这就是算法“知道”结果接收者的方式。此过程的流程由所谓的堆栈处理。

因此,以您的非正式记号(在此示例中,n等于3):

3*(fact(2)) = 3*(2*fact(1)) = 3*(2*(1*fact(0))).

现在,n等于0。内部fact(0)返回1:

3*(2*(1*(1)))) = 3*(2*(1)) = 3*(2) = 6

答案 1 :(得分:0)

您会看到类似这样的

函数fact(int n)就像一个类,每次调用fact(int n)时都会创建该类的实例。通过从同一函数创建它们(调用它们),就可以创建实例链。达到中断条件后,这些函数将开始一个接一个地返回,并且它们返回的值将在return语句return n*fact(n-1)中计算出一个新值,例如return 3*fact(2);