何时使用预购,后序和有序二进制搜索树遍历策略

时间:2012-02-26 20:40:17

标签: data-structures computer-science binary-tree preorder

我最近意识到虽然在我的生活中使用了BST,但我甚至都没有考虑使用任何东西,除了Inorder遍历(虽然我知道并且知道调整程序使用前/后顺序是多么容易遍历)。

在意识到这一点后,我拿出了一些旧的数据结构教科书,并寻找了预订和后序遍历的有用性背后的推理 - 但他们并没有说太多。

什么时候实际使用预订单/后期订单的例子是什么?什么时候比按顺序更有意义?

5 个答案:

答案 0 :(得分:107)

何时使用预订,有序和后订购遍历策略

在您了解在什么情况下使用二叉树的预订,有序和后期订单之前,您必须准确了解每种遍历策略的工作原理。以下面的树为例。

树的根 7 ,最左边的节点 0 ,最右边的节点 10

enter image description here

预订遍历

摘要:从根开始( 7 ),在最右边的节点( 10 )结束

遍历序列:7,1,0,3,2,5,4,6,9,8,10

有序遍历

摘要:从最左边的节点开始( 0 ),在最右边的节点( 10 )结束

遍历序列:0,1,2,3,4,5,6,7,8,9,10

订单后遍历

摘要:从最左边的节点开始( 0 ),以根( 7 )结束

遍历序列:0,2,4,6,5,3,1,8,10,9,7

何时使用预订,有序或订购后?

程序员选择的遍历策略取决于所设计算法的特定需求。目标是速度,因此选择能够为您提供最快的节点的策略。

  1. 如果您知道在检查任何树叶之前需要探索根部,则选择预订,因为您将在所有树叶之前遇到所有树根。

  2. 如果您知道需要在任何节点之前探索所有树叶,请选择后期订单,因为您不会浪费任何时间检查根来搜索树叶。

  3. 如果您知道树在节点中具有固有序列,并且您希望将树展平为原始序列,则应使用按顺序遍历。树将以与创建时相同的方式展平。预订或后序遍历可能无法将树展开回到用于创建它的序列中。

  4. 预订,有序和后序(C ++)的递归算法:

    struct Node{
        int data;
        Node *left, *right;
    };
    void preOrderPrint(Node *root)
    {
      print(root->name);                                  //record root
      if (root->left != NULL) preOrderPrint(root->left);  //traverse left if exists
      if (root->right != NULL) preOrderPrint(root->right);//traverse right if exists
    }
    
    void inOrderPrint(Node *root)
    {
      if (root.left != NULL) inOrderPrint(root->left);   //traverse left if exists
      print(root->name);                                 //record root
      if (root.right != NULL) inOrderPrint(root->right); //traverse right if exists
    }
    
    void postOrderPrint(Node *root)
    {
      if (root->left != NULL) postOrderPrint(root->left);  //traverse left if exists
      if (root->right != NULL) postOrderPrint(root->right);//traverse right if exists
      print(root->name);                                   //record root
    }
    

答案 1 :(得分:22)

如果我想简单地以线性格式打印出树的分层格式,我可能会使用preorder遍历。例如:

- ROOT
    - A
         - B
         - C
    - D
         - E
         - F
             - G

答案 2 :(得分:18)

预订/有序/订购后用法:简单的字词

预购用于创建树的副本 示例:如果要创建树的副本并且需要数组中的节点值,并且当您将索引0中的这些值插入到新树中时,您将获得副本

有序::以非递增顺序获取节点的值

订购后:如果要从树到根删除树

答案 3 :(得分:2)

前后顺序分别与自上而下和自下而上的递归算法有关。如果你想以迭代的方式在二叉树上编写给定的递归算法,这就是你基本上要做的。

进一步观察前序和后序序一起完全指定手头的树,产生紧凑的编码(对于稀疏树至少)。

答案 4 :(得分:1)

有很多地方你认为这种差异起着真正的作用。

我要指出的一个很棒的问题是编译器的代码生成。请考虑以下声明:

x := y + 32

为此生成代码的方式是(天真地,当然)首先生成用于将y加载到寄存器中的代码,将32加载到寄存器中,然后生成添加这两者的指令。因为在你操作它之前必须有一些东西(让我们假设,你总是可以做不变的操作数),你必须这样做。

一般来说,你可以得到这个问题的答案基本上减少到这个:当处理数据结构的不同部分之间存在某种依赖时,差异确实很重要。在打印元素时会看到这一点,在生成代码时(外部状态有所不同,当然也可以单独查看),或者在涉及计算的结构上进行其他类型的计算时,这取决于首先处理的子代