【问题标题】:Inorder tree traversal: Which definition is correct?中序树遍历:哪个定义是正确的?
【发布时间】:2009-01-28 00:56:27
【问题描述】:

我在不久前参加的关于二叉树(不是 BST)的中序遍历(他们也称之为 pancaking)的学术课程中有以下文字:

中序树遍历

在外面画一条线 树。从根的左边开始, 绕到树的外面, 到根的右边。 尽可能靠近树, 但不要穿过树。 (考虑到 树——它的分支和节点——作为 一个坚实的障碍。)的顺序 节点是这一行的顺序 从他们下面经过。如果你是 不确定你什么时候去“下面” 一个节点,记住一个节点“到 左”总是第一位的。

这是使用的示例(与下面的树略有不同)

但是,当我在 google 上进行搜索时,我得到了一个相互矛盾的定义。例如wikipedia example:

中序遍历序列:A、B、C、 D、E、F、G、H、I (leftchild,rootnode,right node)

但根据(我的理解)定义#1,这应该是

A、B、D、C、E、F、G、I、H

谁能澄清哪个定义是正确的?他们可能都描述了不同的遍历方法,但碰巧使用了相同的名称。我无法相信经过同行评审的学术文本是错误的,但无法确定。

【问题讨论】:

  • 不——根据定义一,你在 G 下通过,但你从 I 到 H 并在它之下,然后在 I 之下——所以算法同意。
  • 把一个简单的概念用难以理解的方式来解释,太学术了。

标签: data-structures binary-tree tree-traversal


【解决方案1】:

在我绘制的错误尝试中,这里显示了应该如何挑选它们的顺序。

几乎选择了正在绘制的线正上方的节点。

【讨论】:

  • 这如何回答这个问题?
  • @ForYourOwnGood:正确。
  • 这表明定义完全不冲突:它们具有完全相同的效果。
  • 克里斯已经说过遍历是 A, B, C, D, E, F, G, H, I ,所以通过绘制这个序列可以回答他的问题吗?他已经知道了。
  • 克里斯对第一个定义的解读是错误的,特别是“通过下方”。 Chris 有 BDCE,但你在 D 之前通过了 C。所以。除了 A 上的红线未指向下方(G 下方的红线处于边缘 :-) 之外,此图说明了一切,尤其是。带有“直接在上面”的评论。
【解决方案2】:

忘记定义,应用算法就容易多了:

void inOrderPrint(Node root)
{
  if (root.left != null) inOrderPrint(root.left);
  print(root.name);
  if (root.right != null) inOrderPrint(root.right);
}

只有三行。重新排列前后顺序。

【讨论】:

    【解决方案3】:

    如果您仔细阅读,您会发现第一个“定义”表示从根的 left 开始,并且节点的顺序由您在 under 传递时确定他们。所以B 不是第一个节点,因为你在去A 的路上从左边传递它,然后首先通过 under A 之后你向上并通过 under B。因此,这两个定义似乎给出了相同的结果。

    【讨论】:

      【解决方案4】:

      我个人觉得this lecture 很有帮助。

      【讨论】:

        【解决方案5】:

        两个定义给出相同的结果。不要被第一个示例中的 字母 所迷惑 - 查看路径上的数字。第二个例子确实使用字母来表示路径 - 也许这就是让你失望的原因。

        例如,在您的示例顺序中显示了您认为如何使用第一棵树的算法遍历第二棵树,您将“D”放在“B”之后,但您不应该这样做,因为仍有左手D 的子节点可用(这就是为什么第一项说“这条线通过 underneath 它们的顺序。”

        【讨论】:

          【解决方案6】:

          这可能会迟到,但它可能对以后的任何人有用.. 你只需要忽略虚拟或空节点,例如节点 G 有一个左空节点..考虑到这个空节点会让一切都好起来..

          【讨论】:

            【解决方案7】:

            正确的遍历应该是:叶节点(不是根节点)尽可能向左

            左根右

            A B 空

            C D E

            空 F G

            H I NULL

            F 是根还是左,我不确定

            【讨论】:

              【解决方案8】:

              我认为第一个以a为根的二叉树是一棵构造不正确的二叉树。

              尝试实现树的所有左侧都小于根,树的所有右侧大于或等于根。

              【讨论】:

                【解决方案9】:

                但是根据(我的理解) 定义#1,这应该是

                A, B, D, C, E, F, G, I, H
                

                很遗憾,你的理解是错误的。

                当你到达一个节点时,你必须先下降到一个可用的左节点,然后再查看当前节点,然后再查看可用的右节点。 当你在 C 之前选择 D 时,你并没有先下降到左边的节点。

                【讨论】:

                  【解决方案10】:

                  根据我在 wiki 中提到的内容是正确的,中序遍历的顺序是左-根-右。

                  直到 A、B、C、D、E、F 我想你已经明白了。现在在根 F 之后,下一个节点是 G,它没有左节点但有右节点,因此根据规则 (left-root-right) 它的 null-g-right。现在 I 是 G 的右节点,但我有一个左节点,因此遍历将是 GHI。这是正确的。

                  希望这会有所帮助。

                  【讨论】:

                    【解决方案11】:

                    对于内联树遍历,您必须记住遍历的顺序是左节点右。对于上图,您在读取左侧的任何叶(子)节点之前读取父节点时会发生错误。

                    正确的遍历应该是:叶节点(A)尽可能向左,返回父节点(B),向右移动,但由于 D 在其左侧有一个子节点,因此您再次向下移动(C) ,回到C的父节点(D),回到D的右孩子(E),反向回到根节点(F),移动到右叶(G),移动到G的叶,但是因为它有一个左叶节点移动到那里(H),返回父级(I)。

                    当我将节点列在括号中时,上面的遍历会读取节点。

                    【讨论】:

                      【解决方案12】:

                      包数据结构;

                      公共类 BinaryTreeTraversal {

                      public static Node<Integer> node;
                      
                      public static Node<Integer> sortedArrayToBST(int arr[], int start, int end) {
                          if (start > end)
                              return null;
                      
                          int mid = start + (end - start) / 2;
                          Node<Integer> node = new Node<Integer>();
                          node.setValue(arr[mid]);
                      
                          node.left = sortedArrayToBST(arr, start, mid - 1);
                          node.right = sortedArrayToBST(arr, mid + 1, end);
                          return node;
                      }
                      
                      public static void main(String[] args) {
                      
                          int[] test = new int[] { 1, 2, 3, 4, 5, 6, 7 };
                          Node<Integer> node = sortedArrayToBST(test, 0, test.length - 1);
                      
                          System.out.println("preOrderTraversal >> ");
                      
                          preOrderTraversal(node);
                      
                          System.out.println("");
                      
                          System.out.println("inOrderTraversal >> ");
                      
                          inOrderTraversal(node);
                      
                          System.out.println("");
                      
                          System.out.println("postOrderTraversal >> ");
                      
                          postOrderTraversal(node);
                      
                      }
                      
                      public static void preOrderTraversal(Node<Integer> node) {
                      
                          if (node != null) {
                      
                              System.out.print(" " + node.toString());
                              preOrderTraversal(node.left);
                              preOrderTraversal(node.right);
                          }
                      
                      }
                      
                      public static void inOrderTraversal(Node<Integer> node) {
                      
                          if (node != null) {
                      
                              inOrderTraversal(node.left);
                              System.out.print(" " + node.toString());
                              inOrderTraversal(node.right);
                          }
                      
                      }
                      
                      public static void postOrderTraversal(Node<Integer> node) {
                      
                          if (node != null) {
                      
                              postOrderTraversal(node.left);
                      
                              postOrderTraversal(node.right);
                      
                              System.out.print(" " + node.toString());
                          }
                      
                      }
                      

                      }

                      包数据结构;

                      公共类节点{

                      E value = null;
                      Node<E> left;
                      Node<E> right;
                      
                      public E getValue() {
                          return value;
                      }
                      
                      public void setValue(E value) {
                          this.value = value;
                      }
                      
                      public Node<E> getLeft() {
                          return left;
                      }
                      
                      public void setLeft(Node<E> left) {
                          this.left = left;
                      }
                      
                      public Node<E> getRight() {
                          return right;
                      }
                      
                      public void setRight(Node<E> right) {
                          this.right = right;
                      }
                      
                      @Override
                      public String toString() {
                          return " " +value;
                      }
                      

                      }

                      preOrderTraversal >> 4 2 1 3 6 5 7 inOrderTraversal >> 1 2 3 4 5 6 7 后订单遍历 >> 1 3 2 5 7 6 4

                      【讨论】:

                      • out out is preOrderTraversal >> 4 2 1 3 6 5 7 inOrderTraversal >> 1 2 3 4 5 6 7 postOrderTraversal >> 1 3 2 5 7 6 4
                      【解决方案13】:
                      void
                      inorder (NODE root)
                      {
                        if (root != NULL)
                          {
                            inorder (root->llink);
                            printf ("%d\t", root->info);
                            inorder (root->rlink);
                          }
                      }
                      

                      这是递归定义中序遍历最简单的方法,只需在main函数中调用该函数即可得到给定二叉树的有序遍历。

                      【讨论】:

                        【解决方案14】:

                        预购正确,中序不正确

                        【讨论】:

                          猜你喜欢
                          • 2015-03-28
                          • 1970-01-01
                          • 1970-01-01
                          • 2016-03-14
                          • 2011-03-01
                          • 1970-01-01
                          • 2020-07-16
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多