Inorder 从“最左边的节点”开始,那么为啥 Preorder 不从“最左边的中间节点”开始?

Posted

技术标签:

【中文标题】Inorder 从“最左边的节点”开始,那么为啥 Preorder 不从“最左边的中间节点”开始?【英文标题】:Inorder starts from the "leftmost left node" so why doesn't Preorder start from "leftmost middle node"?Inorder 从“最左边的节点”开始,那么为什么 Preorder 不从“最左边的中间节点”开始? 【发布时间】:2013-08-29 21:15:08 【问题描述】:

考虑这棵树:

           7
         /    \
       /        \
      /          \
     1            9
    /  \         /  \
   0    3       8   10 
       / \
      2   5
         / \
        4   6

顺序:

0、1、2、3、4、5、6、7、8、9、10

预购:

7、1、0、3、2、5、4、6、9、8、10

在进行中序遍历时,首先找到最左边的节点,然后从那里开始遍历。但是当涉及到 Preorder 时,不应用相同的逻辑(如 最左边的中间节点

在上面的树中,除了根 7 之外,还有 1 和 9 都是中间节点。 1 是最左边的中间节点,9 是最右边的中间节点。按照上面InOrder应用的逻辑,Preorder遍历应该是从节点1开始,即最左边的中间节点,但事实并非如此,为什么?

为什么Inorder中的遍历是从最左边的节点开始的,而PreOrder的遍历却不是从最左边的中间节点 em>

谢谢, 克里斯。

【问题讨论】:

【参考方案1】:

Preorder 总是将父代放在其后代之前(即它的定义),因此它必须从根开始。如果您愿意,可以使用术语“最中间的中间节点”作为根。

preorder 的典型用法是标准函数表示法:如果您有类似

f(g(x, h(y, z)))

那么这是以下表达式树的预排序符号,它使用函数名称作为内部节点,变量作为离开节点:

      f
      |
      g
     / \
    x   h
       / \
      y   z

另一方面,+* 等运算符的常用符号使用 inorder

a + b * c

是中序符号

    +
   / \
  a   *
     / \
    b   c

如果我们使用*+ 绑定更强的标准数学优先规则。

在reverse polish notation 中编写表达式将是postorder 的一个示例。

【讨论】:

这种方式有什么特别的原因吗?将父母放在后代之前。 @ChrisOdney 我编辑了我的答案,以展示一些在实践中使用不同顺序的示例。这些应该表明,在普通的数学或编程语言使用中,前序和中序似乎相当自然。【参考方案2】:

中序:遍历左子树;访问当前节点;遍历右子树;

预购:访问当前节点;遍历左子树;遍历右子树;

后序:遍历左子树;遍历右子树;访问当前节点;

请注意,除非缺少左子树,否则 Inorder 和 Preorder 中永远不会有相同的节点。

但是,如果存在左子树,您可以在 Inorder 和 PostOrder 表示中拥有相同的节点。

【讨论】:

以上是关于Inorder 从“最左边的节点”开始,那么为啥 Preorder 不从“最左边的中间节点”开始?的主要内容,如果未能解决你的问题,请参考以下文章

java二叉树中序遍历 的递归算法没有看懂。。search(data.getLeft());之后不就回到最左边的一个

java 106.从Inorder和Postorder Traversal构建二叉树(#)。java

java 106.从Inorder和Postorder Traversal构建二叉树(#)。java

java 106.从Inorder和Postorder Traversal构建二叉树(#)。java

java 106.从Inorder和Postorder Traversal构建二叉树(#)。java

java 106.从Inorder和Postorder Traversal构建二叉树(#)。java