理解Python 2中的递归(Think Python,练习5)

时间:2014-01-10 16:06:30

标签: python algorithm recursion

我正在通过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的函数调用是非常不切实际的。

2 个答案:

答案 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)

所以我遇到了同样的问题来理解这个练习,我认为没有什么比模式或图片更容易理解它了,所以这里是我对代码的第一次迭代的解释(使用这个您可以轻松理解其余代码的相同逻辑:

Explanation