我正在通过Think Python,我已经达到递归,这对我来说是一个很难理解的痛苦。
There's this exercise,第5位,它向我展示了这段代码:
def draw(t, length, n):
if n == 0:
return
angle = 50 #sets angle
fd(t, length*n) #make a turtle() "t" go forward length*n pixels while drawing
lt(t, angle) #makes turtle "t" turn left on itself "angle" (50) degrees
draw(t, length, n-1) #1st call
rt(t, 2*angle) #makes turtle "t" turn right "2*angle" (100) degrees
draw(t, length, n-1) #2nd call
lt(t, angle) #makes turtle "t" turn left "angle" (50) degrees
bk(t, length*n) #makes turtle "t" go backwards length*n pixels
并要求我思考它的作用,然后运行它。我跑了它,我很难理解它为什么会这样做。 这是一个更加复杂的递归案例,书籍用来解释这个设备,我无法理解。 让我们使用例如2的n来理解这个问题的简单实例: 我可以得出的结果是代码调用自己直到n = 0直到第一个连续调用,然后将控制返回到n = 1并使剩余的代码行从调用1调用到它。它进行第二次调用n = 0并返回,但我无法理解它返回程序控制的函数的实例。 我很高兴有人能指出我正确的方向,如何自己思考这种递归代码,我怎样才能使用它(当一个for语句不能完全实现它时)和一种模式化方法它的工作方式(例如某种图表?)。 我有这个:
function called with n=2
function called with n=1
function called with n=0; returns to:
function called with n=1 makes the 2nd call to the function with n=0
function called with n=0; returns to where?
??????
正如你所看到的那样,假设n = 7的函数调用是非常不切实际的。
答案 0 :(得分:1)
函数始终直接返回其调用者。你的递归函数做了一些工作,调用自身,然后当调用返回时,做一些更多的工作,然后调用自己另一个时间,然后当它返回时,做一些最后的工作,在函数结束之前和它自己返回:
work
call
work
call
work
return
也就是说,除非n == 0
为真,否则函数会立即返回。每个递归调用都会从n
中减去1,因此只要n
为正数,您的递归就会在某个时刻结束。
递归只是再次运行相同函数的行为,因此您可以使用正在执行的相同作业替换上图中的每个call
。让我们这样做一次:
n = 2
work
n = 1
work
call
work
call
work
work
n = 1
work
call
work
call
work
return
work
return
我添加了n
的值,前提是我们从n = 2
开始。当然,一旦你到达n = 0
,呼叫立即返回;我们也可以填写:
n = 2
work
n = 1
work
n = 0
return
work
n = 0
return
work
return
work
n = 1
work
n = 0
return
work
n = 0
return
work
return
work
return
现在我们为n = 2
提供了递归函数的完整调用树。对于n
的较高值,只需在上一级有work - call - work - call - work - return
行的任何位置保持缩进和填充call
行,并且可以为任何递归函数构建完整的调用树
答案 1 :(得分:1)