使用递归在Python中画一棵分形树



我正在尝试使用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)。在这里,branchLen25

现在,它可以进行t.forward(25)t.right(20)。然后进行tree(25-15, t)。这是对tree的新电话,在该新调用中,branchLen10

因此,新调用确实t.forward(10)t.right(20)。然后进行tree(10-15, t)。这是对tree的新调用,在该新调用中,branchLen-5。因此,由于if失败,因此新调用会立即返回,然后我们返回到branchLen10的呼叫。它执行t.left(40),然后调用tree(10-10, t)。同样,一个新调用,其中branchLen0,它立即返回,因此我们又回到了branchLen10的呼叫。我们进行t.right(20),然后进行t.backward(10),然后返回。

现在我们回到了branchLen为25的外部呼叫。它继续使用t.left(40),然后呼叫tree(25-10, t)。这再次是对tree的新调用,但是时间branchLen15,而不是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)行。

最新更新