我试图更好地理解递归以及return语句的工作原理。因此,我正在查看一段代码,用于识别与给定术语相关的斐波纳契数 - 在这种情况下,4。我很难理解else语句。
def f(n):
if n == 0:
return 0
if n == 1:
return 1
else:
return f(n-1) + f(n-2)
f(4)
我尝试使用Visualize Python来检查每一步发生的事情,但是当它碰到else语句时我迷路了。
看起来它取n的值并减去1,创建一个新的n值3,它返回到函数定义。所以它似乎只返回else语句中第一个函数的值。但是,写入else语句是为了返回2个函数f(n-1)+ f(n-2)的总和,在这种情况下我认为返回值是5?你能在一起添加2个功能吗?
提前感谢您的帮助。
以下是Visualize Python Sum of 2 functions
中代码的链接答案 0 :(得分:33)
如有疑问,请将其分解。
树流实际上与实际控制流程相反,但是一旦理解了调用顺序,它就会变得更加清晰。这里要理解的是,你不断将较大的计算分解为较小的计算总和,并在你遇到基本情况时停止(if
语句)。现在,您可以执行所有小型计算,并将这些小型计算的结果组合在一起,形成更大,更大的结果,直到您得到最终答案。
每次递归调用都会遇到基本情况时,它将返回1或0,具体取决于遇到的情况。该值将返回给前一个调用者。要理解,请考虑:
f(1)3 + f(0)3
请注意,下标表示递归调用树的深度。该呼叫由f(2)2
发出。首先计算f(1)3
,并将1
返回f(2)2
。然后计算f(0)3
,0
返回f(2)2
。将两个返回值相加,结果为1
。
f(2)2
然后将 1
返回给 it 的人,在这种情况下恰好是f(3)1
。 f(3)1
调用了f(2)2 + f(1)2
,同时另一个f(1)2
也将1
返回给f(3)1
,f(2)2
现在将2
的结果添加到f(3)1
2
。
f(4)0
现在将f(3)1 + f(2)1
传递给f(4)0
,其来电者恰好呼叫f(4)0
......所以就这样了。
另一种看待这种情况的方法是从实际进行的第一次函数调用开始:f(3)1 + f(2)1
。
f(3)1
计算f(2)2 + f(1)2
。但要计算f(2)1
,它需要知道f(1)2 + f(0)2
,同样,要计算{{1}},它需要知道{{1}},依此类推。
答案 1 :(得分:2)
添加一些打印语句也有助于澄清序列:
def f(n):
print("Number received:", n)
if n == 0:
return 0
if n == 1:
return 1
else:
print("---- First recursion ----")
a = f(n-1)
print("---- Second recursion ----")
b = f(n-2)
print(" a=:",a,"; b=",b,"; returning:", a+b)
return a + b
print("Final f(4)=", f(4))
输出:
Number received: 4
---- First recursion ----
Number received: 3
---- First recursion ----
Number received: 2
---- First recursion ----
Number received: 1
---- Second recursion ----
Number received: 0
a=: 1 ; b= 0 ; returning: 1
---- Second recursion ----
Number received: 1
a=: 1 ; b= 1 ; returning: 2
---- Second recursion ----
Number received: 2
---- First recursion ----
Number received: 1
---- Second recursion ----
Number received: 0
a=: 1 ; b= 0 ; returning: 1
a=: 2 ; b= 1 ; returning: 3
Final f(4)= 3