Data structures 顺序树遍历:哪个定义是正确的?

Data structures 顺序树遍历:哪个定义是正确的?,data-structures,binary-tree,tree-traversal,Data Structures,Binary Tree,Tree Traversal,我有一篇文章来自我不久前参加的一门学术课程,内容是关于二叉树(非BST)的有序遍历(他们也叫它煎饼): 有序树遍历 画一条线围绕着这个盒子的外面 树。从根的左侧开始, 绕着树的外面走, 在根的右边结束。 尽量靠近树, 但是不要穿过那棵树。(想想 树(其分支和节点)作为 一道坚实的屏障。)的顺序 节点是该行的顺序 从他们下面经过。如果你是 不确定你什么时候去“地下” 一个节点,记住一个节点“到 “左”总是第一位 下面是使用的示例(与下面的树稍有不同) 然而,当我在谷歌上搜索时,我得到了一个相互冲

我有一篇文章来自我不久前参加的一门学术课程,内容是关于二叉树(非BST)的有序遍历(他们也叫它煎饼):

有序树遍历

画一条线围绕着这个盒子的外面 树。从根的左侧开始, 绕着树的外面走, 在根的右边结束。 尽量靠近树, 但是不要穿过那棵树。(想想 树(其分支和节点)作为 一道坚实的屏障。)的顺序 节点是该行的顺序 从他们下面经过。如果你是 不确定你什么时候去“地下” 一个节点,记住一个节点“到 “左”总是第一位

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

然而,当我在谷歌上搜索时,我得到了一个相互冲突的定义。例如:

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

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

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


有人能澄清哪个定义是正确的吗?它们可能都描述了不同的遍历方法,但恰好使用了相同的名称。我很难相信同行评议的学术文本是错误的,但无法确定。

如果仔细阅读,您会发现第一个“定义”是从根的左侧开始的,节点的顺序取决于您经过它们的时间。因此,
B
不是第一个节点,因为您在前往
A
的途中从左侧传递它,然后在
A
下首先传递,然后在
B
下传递。因此,这两个定义似乎给出了相同的结果。

在我对绘图的错误尝试中,这里的顺序显示了如何选取它们。


基本上是拾取正在绘制的线正上方的节点

两个定义给出了相同的结果。不要被第一个例子中的字母所愚弄——看看沿途的数字。第二个例子确实使用字母来表示路径——也许这就是让你感到不舒服的地方

例如,在显示您认为第二棵树将如何使用第一棵树的算法遍历的示例顺序中,您将“D”放在“B”之后,但不应该放在“B”之后,因为仍然有一个D的左侧子节点可用(这就是为什么第一项显示“此行在它们下方通过的顺序”)

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

A, B, D, C, E, F, G, I, H
不幸的是,你的理解是错误的

无论何时到达节点,都必须先下降到可用的左侧节点,然后再查看当前节点,然后再查看可用的右侧节点。
当您在C之前选择D时,您没有首先下降到左侧节点。

忘记定义,只应用算法要简单得多:

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

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

嘿,根据我在wiki中提到的,按顺序遍历的顺序是从左到右

直到A,B,C,D,E,F我想你们已经理解了。现在在根F之后的下一个节点是G,它没有左节点,而是右节点,所以根据规则(左根右)它是空的G-右。现在我是G的右节点,但我有左节点,因此遍历应该是GHI。这是正确的


希望这能有所帮助。

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


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


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

我个人觉得非常有用。

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


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

这可能很晚,但对以后的任何人都有用。。
你只需要不忽略伪节点或空节点,例如节点g有一个左空节点。考虑到这个空节点会使一切正常。

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

左根右 A B空 C D E 空F G HI空值 F是root或left,我不确定

包数据结构

公共类二叉树四叉树{

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());
    }

}
公共静态节点;
公共静态节点排序DarrayToBST(int arr[],int start,int end){
如果(开始>结束)
返回null;
int mid=start+(end-start)/2;
节点=新节点();
node.setValue(arr[mid]);
node.left=sortedarray-tobst(arr、start、mid-1);
node.right=sortedArrayToBST(arr,中间+1,结束);
返回节点;
}
公共静态void main(字符串[]args){
int[]test=新的int[]{1,2,3,4,5,6,7};
节点节点=SortedDarrayToBST(测试,0,测试长度-1);
System.out.println(“preOrderTraversal>>”;
预订单行程(节点);
System.out.println(“”);
System.out.println(“inOrderTraversal>>”;
inOrderTraversal(节点);
System.out.println(“”);
System.out.println(“postOrderTraversal>>”;
postOrderTraversal(节点);
}
公共静态void preOrderTraversal(节点){
如果(节点!=null){
void
inorder (NODE root)
{
  if (root != NULL)
    {
      inorder (root->llink);
      printf ("%d\t", root->info);
      inorder (root->rlink);
    }
}