我正在尝试使用python绘制分形树。特别是,我试图理解以下代码,在此处找到
def tree(branchLen,t):
if branchLen > 5:
t.forward(branchLen)
t.right(20)
tree(branchLen-15,t)
t.left(40)
tree(branchLen-10,t)
t.right(20)
t.backward(branchLen)
我具体的问题是,我不明白最后一步完成后发生了什么(即t.backward(branchlen)
)。此步骤之后,变量branchlen
的值如何变化?我试图遵循算法,并使用铅笔和纸手动构造树,但无济于事。任何人的帮助将不胜感激。提前致谢!
我不明白最后一步完成后发生了什么(即
t.backward(branchlen)
)。
什么也没有发生;您只需返回您的呼叫者,然后在tree
调用后在线恢复。
当然,因为这是递归功能,所以您的呼叫者通常将是tree
的另一个实例(除非您一直沿堆栈的顶部一直升)。
此步骤之后变量BranchLen的值如何变化?
不是。但是tree
的每个实例都有自己的当地人。
所以,让我们从顶部开始。
首先,我们打电话给tree(25, t)
。在这里,branchLen
是25
。
现在,它可以进行t.forward(25)
和t.right(20)
。然后进行tree(25-15, t)
。这是对tree
的新电话,在该新调用中,branchLen
是10
。
因此,新调用确实t.forward(10)
和t.right(20)
。然后进行tree(10-15, t)
。这是对tree
的新调用,在该新调用中,branchLen
是-5
。因此,由于if
失败,因此新调用会立即返回,然后我们返回到branchLen
为10
的呼叫。它执行t.left(40)
,然后调用tree(10-10, t)
。同样,一个新调用,其中branchLen
为0
,它立即返回,因此我们又回到了branchLen
为10
的呼叫。我们进行t.right(20)
,然后进行t.backward(10)
,然后返回。
现在我们回到了branchLen
为25的外部呼叫。它继续使用t.left(40)
,然后呼叫tree(25-10, t)
。这再次是对tree
的新调用,但是时间branchLen
是15
,而不是10
。一切与上一段几乎相同,所以我不会重复,然后以返回的呼叫结束。
现在我们回到了外部呼叫,其中branchLen
再次为25。它继续使用t.right(20)
然后t.backward(25)
,然后完成,然后返回。
既然是由我们的顶级代码调用的,那么我们就完成了。
如果递归仍在抛弃您,让我们制作一个仅进行2个步骤而不是n个步骤的非收回版本:
def tree(branchLen,t):
if branchLen > 5:
t.forward(branchLen)
t.right(20)
little_tree(branchLen-15,t)
t.left(40)
little_tree(branchLen-10,t)
t.right(20)
t.backward(branchLen)
def little_tree(littleBranchLen,lt):
if littleBranchLen > 5:
lt.forward(littleBranchLen)
lt.right(20)
lt.left(40)
lt.right(20)
lt.backward(littleBranchLen)
现在应该很明显,当tree
首次调用little_tree
时,当它返回时,它会返回到tree
中的t.left(40)
行。