Python 为什么这个前序遍历会返回最后一个节点?

Python 为什么这个前序遍历会返回最后一个节点?,python,recursion,linked-list,binary-tree,preorder,Python,Recursion,Linked List,Binary Tree,Preorder,我理解为什么字母[A,B,D]被添加到列表中。但我不明白最后两个字母[E,C]是怎么加起来的。 在pre_order('C',nodes')之后,字母'C'没有剩余子级,函数如何知道向字母'B'前进一步并检查其子级,等等?请参见树图像: 执行后,函数返回到调用它的任何位置,在本例中,即调用同一个函数,但参数不同 让我们在您的示例中看看它是如何工作的。每个缩进都是一个新的执行-看看我们如何返回到上一个缩进并继续 我们从节点A上带有空列表的预订单开始 将A追加到当前列表,新列表=[A] 首先如

我理解为什么字母[A,B,D]被添加到列表中。但我不明白最后两个字母[E,C]是怎么加起来的。 在pre_order('C',nodes')之后,字母'C'没有剩余子级,函数如何知道向字母'B'前进一步并检查其子级,等等?请参见树图像:


执行后,函数返回到调用它的任何位置,在本例中,即调用同一个函数,但参数不同

让我们在您的示例中看看它是如何工作的。每个缩进都是一个新的执行-看看我们如何返回到上一个缩进并继续

  • 我们从节点A上带有空列表的预订单开始
    • 将A追加到当前列表,新列表=[A]
    • 首先
      如果
      命中,那么我们使用列表在B上执行:
      • 将B追加到当前列表[A],新列表=[A,B]
      • 首先
        如果
        命中,那么我们使用列表在D上执行:
        • 将D追加到当前列表[A,B],新列表=[A,B,D]
        • 第一个
          如果
          没有命中,因为D没有左孩子
        • 第二个
          如果因为D没有合适的孩子而未命中
        • 返回[A、B、D]
      • 我们得到了内部执行的结果,并在开始的地方继续执行(在B中)
      • 第二个
        如果
        命中,那么我们使用列表在E上执行(现在由于可变性在内部函数中更改)
        • 将E追加到当前列表[A,B,D],新列表=[A,B,D,E]
        • 第一个
          ,如果因E没有左子女而未命中
        • 第二个
          如果因为E没有合适的孩子而未命中
        • 返回[A、B、D、E]
      • 我们得到了内部执行的结果,并在开始的地方继续执行(在B中)
      • 返回[A、B、D、E]
    • 我们得到了内部执行的结果,并继续执行(在A中)
    • 第二个
      如果
      命中,那么我们使用列表在C上执行(现在在内部执行中更改了多次)
      • 将C追加到当前列表[A,B,D,E],新列表=[A,B,D,E,C]
      • 第一个
        如果
        没有命中,因为C没有左子级
      • 第二个
        如果
        没有命中,因为C没有正确的子对象
      • 返回[A、B、D、E、C]
    • 我们得到了内部执行的结果,并继续执行(在A中)
    • 返回[A、B、D、E、C]
  • 我们回到我们第一次执行预订单的地方——也就是说,一个打印函数

[列表中可能有轻微的打字错误和小错误,我复制粘贴了大部分内容,可能我忘记了更改某些内容]

Google Recurence and preorder。当某个对象没有子对象或子对象已被检查时,该函数返回并继续执行它所执行的任何函数。@h4z3,它不会继续执行执行它的任何函数。在字母“D”之后,它用字母“E”调用函数。为什么?是的,它确实在继续——但执行它的是同一个函数(具有不同的参数)。这就是递归(很抱歉我之前的错误,我是用音译而不是翻译的)。@GoldenRetriever这就是你如何按顺序遍历一棵树。谢谢你的详细描述。然而,当函数被调用时使用的参数与第一次调用它的参数相同,它怎么会不在无限循环中运行呢?因为,假设它再次被B调用,是什么阻止它再次访问B的左子级?它返回到调用,而不是函数的开头。基本上,你得到了字面上的同一行(如果你数字,那么它更容易想象),但在执行后。就像
x=len(range(10))+1
将首先进入
range(10)
并创建它并返回它被调用的位置,然后
len
执行并返回它被调用的位置,然后
+
执行并返回,然后
x
被分配
10+1
不关心它是如何得到它的
10
len
),也不关心它的结果会发生什么(
x=
)。之前的状态被存储,以便程序知道它需要在哪里继续。它存储在一个特殊的堆栈上,“堆栈溢出”是一个异常,当您收到太多调用(例如太长或无限递归)并且您没有地方存储以前的状态时,会引发该异常。
def pre_order(root, nodes):
    nodes.append(root.data)
    if root and root.left:
        pre_order(root.left, nodes)
    if root and root.right:
        pre_order(root.right, nodes)
    return nodes

    print(pre_order(root, [])) #prints ['A', 'B', 'D', 'E', 'C']