[英]Recursion in depth (Python)
检查以下代码:
>>> def fib(x):
... if x == 0 or x == 1:
... return 1
... else:
... return fib(x-1) + fib(x-2)
>>> print(fib(4))
根据SoloLearn Python教程(针对Recursion)中的注释,代码的工作原理如下:
1. fib(4) = fib(3) + fib(2)
2. = (fib(2) + fib(1)) + (fib(1) + fib(0))
3. = fib(1) + fib(0) + fib(1) + fib(1) + fib(0)
4. = 1+ 1 + 1 + 1 + 1
5. = 5
在第2行之后,只有fib(2)
应该成为fib()
函数的else部分,对吧? 两个fib(1)
和单个fib(0)
满足fib()
函数的if部分的标准。 所以返回1。 我的问题是,为什么在第3行, fib(1) + fib(0) + fib(1) + fib(1) + fib(0)
都被1替换然后加入?
请原谅我提出这样一个noob问题。
这是一个双递归函数,因此它的调用结果是调用的树结构,其基本情况为fib(1)和fib(0)
fib(4) = fib(3) + fib(2)
/ \ / \
fib(4) = ( fib(2) + fib(1) ) + ( fib(1) + fib(0) )
/ \ | | |
fib(4) = ( ( fib(1) + fib(0) ) + fib(1) ) + ( fib(1) + fib(0) )
| | | | |
fib(4) = ( ( 1 + 1 ) + 1 ) + ( 1 + 1 )
\ / | \ /
fib(4) = ( ( 2 ) + 1 ) + ( 2 )
\ / |
fib(4) = ( 3 ) + ( 2 )
\ /
fib(4) = 5
您还可以通过在正确的位置添加一些打印件以及辅助参数以及其他一些小的更改来可视化函数的工作。
>>> def fib(n, nivel=0):
if n==0 or n==1:
print(" "*nivel,"fib(",n,")=1")
return 1
else:
print(" "*nivel,"fib(",n,")")
result = fib(n-1,nivel+1) + fib(n-2,nivel+1)
print(" "*nivel,"fib(",n,")=",result)
return result
>>> fib(4)
fib( 4 )
fib( 3 )
fib( 2 )
fib( 1 )=1
fib( 0 )=1
fib( 2 )= 2
fib( 1 )=1
fib( 3 )= 3
fib( 2 )
fib( 1 )=1
fib( 0 )=1
fib( 2 )= 2
fib( 4 )= 5
5
>>>
在这里,您可以注意到呼叫按顺序从左到右,从下到上解决
我相信代码如何工作的描述具有误导性,因为它似乎表明,当从一行到另一行时,并不是每个值都被评估。 如果我们通过它调用的函数(或它返回的值)替换下一行,并在示例中添加括号,我们得到以下内容,这可能有助于您更好地理解该代码的内部工作方式:
1. fib(4)
2. = fib(3) + fib(2)
3. = (fib(2) + fib(1)) + (fib(1) + fib(0))
4. = ((fib(1) + fib(0)) + 1) + (1 + 1)
5. = 1 + 1 + 1 + 2
6. = 5
@MorganThrapp是对的。 更具体地说,递归函数fib
的基本情况是:
if x==0 or x==1:
return 1
当调用fib(1)
或fib(0)
时触发该子句。 在编程用语中,函数计算其返回值,此处为1
。
在你的fib(4)
的例子中,使用1
或0
输入将fib
调用五次,并将这些结果全部加在一起,这将导致你的最终返回值为5
,这是从原始调用fib(4)
返回的fib(4)
并立即进入print
功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.