预订到订单后的遍历

时间:2010-12-27 10:13:45

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

如果二叉搜索树的预订遍历是6,2,1,4,3,7,10,9,11,那么如何进行后期遍历?

11 个答案:

答案 0 :(得分:27)

您将获得树的预订遍历,该遍历遍历:输出,左移,右移。

由于后序遍历来自BST,您可以通过对数字进行排序来推断顺序遍历中的有序遍历(遍历左,输出,遍历右)。在您的示例中,有序遍历为1,2,3,4,6,7,9,10,11。

然后我们可以从两次遍历构建原始树。让我们使用一个更简单的例子:

  • 预购:2,1,4,3
  • 有序:1,2,3,4

预先遍序遍历给我们树的根作为2.按顺序遍历告诉我们1落入左子树,3,4落入右子树。左子树的结构是微不足道的,因为它包含单个元素。通过从原始预订遍历中获取该子树中的元素的顺序来推导出右子树的预订遍历:4,3。由此我们知道右子树的根是4并且从有序遍历(3,4)我们知道3落入左子树。我们的最终树看起来像这样:

  2
 / \
1   4
   /
  3

使用树结构,我们可以通过遍历树来获得后序遍历:遍历左,遍历右,输出。对于此示例,后序遍历为1,3,4,2。

概括算法:

  1. 预先遍历遍历中的第一个元素是树的根。小于根的元素构成左子树。大于根的元素构成右子树。
  2. 使用步骤1找到左右子树的结构,其中包含预先遍历遍历,该遍历遍历由我们在该子树中按照它们在原始预订中出现的顺序放置的元素组成遍历。
  3. 按顺序遍历生成的树,以获得与给定的预订遍历相关联的后订单遍历。
  4. 使用上述算法,与问题中的预先遍历相关联的后序遍历为:1,3,4,2,9,11,10,7,6。将其留作练习

答案 1 :(得分:9)

预订 =按当前节点的顺序输出二叉树的值,然后输出左子树,然后输出右子树。

后序 =按左子树的顺序输出二叉树的值,然后输出右子树,即当前节点。

在二进制搜索树中,左子树中所有节点的值小于当前节点的值;和相似的正确子树。因此,如果您知道二叉搜索树的预订转储的开始(即其根节点的值),您可以轻松地将整个转储分解为根节点值,左子树节点的值以及值正确的子树节点。

要按顺序输出树,应用递归和输出重新排序。这项任务留待读者阅读。

答案 2 :(得分:4)

基于Ondrej Tucny的回答。仅适用于BST 例如:

     20  
    /  \  
   10  30  
   /\    \  
  6  15   35  

预购= 20 10 6 15 30 35
邮政= 6 15 10 35 30 20

对于BST,在Preorder遍历;数组的第一个元素是20.这是我们树的根。数组中小于20的所有数字形成其左子树,而更大的数字形成右子树。

//N = number of nodes in BST (size of traversal array)
int post[N] = {0}; 
int i =0;

void PretoPost(int pre[],int l,int r){
  if(l==r){post[i++] = pre[l]; return;}
  //pre[l] is root
  //Divide array in lesser numbers and greater numbers and then call this function on them recursively  
  for(int j=l+1;j<=r;j++) 
      if(pre[j]>pre[l])
          break;
  PretoPost(a,l+1,j-1); // add left node
  PretoPost(a,j,r); //add right node
  //root should go in the end
  post[i++] = pre[l]; 
  return;
 }

如果有任何错误,请纠正我。

答案 3 :(得分:3)

您将获得预订遍历结果。然后将值放到合适的二叉搜索树中,并按照获得的BST的后序遍历算法。

答案 4 :(得分:3)

这是python中从前到后遍历的代码。 我正在构造一棵树,以便您可以找到任何类型的遍历

def postorder(root):
    if root==None:
        return
    postorder(root.left)
    print(root.data,end=" ")
    postorder(root.right)

def preordertoposorder(a,n):
    root=Node(a[0])
    top=Node(0)
    temp=Node(0)
    temp=None
    stack=[]
    stack.append(root)
    for i in range(1,len(a)):
        while len(stack)!=0 and a[i]>stack[-1].data:
            temp=stack.pop()
        if temp!=None:
            temp.right=Node(a[i])
            stack.append(temp.right)
        else:
            stack[-1].left=Node(a[i])
            stack.append(stack[-1].left)
    return root
class Node:
    def __init__(self,data):
        self.data=data
        self.left=None
        self.right=None  
a=[40,30,35,80,100]
n=5
root=preordertoposorder(a,n)
postorder(root)
# print(root.data)
# print(root.left.data)
# print(root.right.data)
# print(root.left.right.data)
# print(root.right.right.data)

答案 5 :(得分:1)

我知道这已经过时了,但有一个更好的解决方案。

我们不必重建BST以从预购中获得订单。

这是一个简单的python代码,它递归地执行:

import itertools

def postorder(preorder):
    if not preorder:
        return []
    else:
        root = preorder[0]
        left = list(itertools.takewhile(lambda x: x < root, preorder[1:]))
        right = preorder[len(left) + 1:]
        return postorder(left) + postorder(right) + [root]

if __name__ == '__main__':
    preorder = [20, 10, 6, 15, 30, 35]
    print(postorder(preorder))

<强>输出:

 [6, 15, 10, 35, 30, 20]

<强>解释

我们知道我们正在预订中。这意味着根位于BST中值列表的索引0。我们知道根后面的元素是:

  • 首先:小于root的元素,属于根的左子树
  • 第二个:大于root的元素,属于根的右子树

然后我们只是递归调用两个子树上的函数(仍然是预先订购的),然后是链left + right + root(这是后订购)。

答案 6 :(得分:1)

如果您已获得预订,并且您想将其转换为延期交货。然后你应该记住,在BST中按顺序总是按升序给出数字。因此你既有顺序也有预编令来构造树。

预购:6, 2, 1, 4, 3, 7, 10, 9, 11

inorder:1, 2, 3, 4, 6, 7, 9, 10, 11

及其后序:1 3 4 2 9 11 10 7 6

答案 7 :(得分:1)

这里以二进制搜索树的预先遍序遍历在数组中给出。 所以预订数组的第一个元素将是BST的根。我们将找到BST的左边部分和BST的右边部分。预定数组中的所有元素都比root更小,将是左边的节点和所有元素在pre中-order数组大于root将是右节点。

#include <bits/stdc++.h>
using namespace std;
int arr[1002];
int no_ans = 0;
int n = 1000;
int ans[1002] ;
int k = 0;

int find_ind(int l,int r,int x){
    int index = -1; 
    for(int i = l;i<=r;i++){
        if(x<arr[i]){
            index = i;
            break;
        }
    }
    if(index == -1)return index;
    for(int i =l+1;i<index;i++){
        if(arr[i] > x){
            no_ans = 1;
            return index;
        }
    }
    for(int i = index;i<=r;i++){
        if(arr[i]<x){
            no_ans = 1;
            return index;
        }
    }
    return index;

}

void postorder(int l ,int r){

    if(l < 0 || r >= n || l >r ) return;
    ans[k++] = arr[l];
    if(l==r) return;
    int index = find_ind(l+1,r,arr[l]);
    if(no_ans){
        return;
    }
    if(index!=-1){
        postorder(index,r);
        postorder(l+1,index-1);
    }
    else{
        postorder(l+1,r);
    }
}

int main(void){

    int t;
    scanf("%d",&t);
    while(t--){
        no_ans = 0;
        int n ;
        scanf("%d",&n);

        for(int i = 0;i<n;i++){
            cin>>arr[i];
        }
        postorder(0,n-1);
        if(no_ans){
            cout<<"NO"<<endl;
        }
        else{

            for(int i =n-1;i>=0;i--){
                cout<<ans[i]<<" ";
            }
            cout<<endl;
        }
    }

    return 0;
} 

答案 8 :(得分:1)

正如我们所知,preOrder遵循父,左,右系列。

为了构建树,我们需要遵循几个基本步骤 - :

你的问题包括系列6,2,1,4,3,7,10,9,11

分 - :

  1. 第一个系列将是root(parent),即6
  2. 2.找到大于6的数字所以在这个系列中,7是本系列中第一个更大的数字,所以右边的节点将从这里开始,左边是这个数字(7)是你的左子树。

                          6
                        /   \
                       2     7
                     /  \     \
                    1    4     10
                         /     / \
                         3     9  11
    

    3.同样的方式遵循BST的基本规则,即左,右,右

    一系列的后序将是L,R,N,即1,3,4,2,9,11,10,7,6

答案 9 :(得分:0)

完整代码

class Tree:
    def __init__(self, data = None):
        self.left = None
        self.right = None
        self.data = data

    def add(self, data):
        if self.data is None:
            self.data = data
        else:
            if data < self.data:
                if self.left is None:
                    self.left = Tree(data)
                else:
                    self.left.add(data)
            elif data > self.data:
                if self.right is None:
                    self.right = Tree(data)
                else:
                    self.right.add(data)
    def inOrder(self):
        if self.data:
            if self.left is not None:
                self.left.inOrder()
            print(self.data)
            if self.right is not None:
                self.right.inOrder()

    def postOrder(self):
        if self.data:
            if self.left is not None:
                self.left.postOrder()
            if self.right is not None:
                self.right.postOrder()
            print(self.data)

    def preOrder(self):
        if self.data:
            print(self.data)
            if self.left is not None:
                self.left.preOrder()
            if self.right is not None:
                self.right.preOrder()
arr = [6, 2, 1, 4, 3, 7, 10, 9, 11]
root = Tree()
for i in range(len(arr)):
    root.add(arr[i])
print(root.inOrder())

答案 10 :(得分:0)

由于它是二叉搜索树,因此顺序遍历将始终是排序后的元素。 (左<根<右)

因此,您可以轻松地首先编写其有序遍历结果,即:1,2,3,4,6,7,9,10,11

已预订:6、2、1、4、3、7、10、9、11

顺序:左,根,右 预购:根,左,右 后置顺序:左,右,根

现在,我们从预订单中获得了根为6的信息。

现在,使用有序和预订结果: 步骤1:

             6
            / \
           /   \
          /     \
         /       \
   {1,2,3,4}  {7,9,10,11}

第2步:使用有序遍历,下一个根是2:

             6
            / \
           /   \
          /     \
         /       \
        2  {7,9,10,11}
       / \
      /   \
     /     \
    1    {3,4}

步骤3:同样,下一个根是4:

             6
            / \
           /   \
          /     \
         /       \
        2  {7,9,10,11}
       / \
      /   \
     /     \
    1       4
           /
          3

步骤4:下一个根为3,但没有其他元素适合“ 3”的子树。现在考虑下一个根为7,

             6
            / \
           /   \
          /     \
         /       \
        2         7
       / \         \
      /   \       {9,10,11}
     /     \
    1       4
           /
          3

步骤5:下一个根是10:

             6
            / \
           /   \
          /     \
         /       \
        2         7
       / \         \
      /   \         10
     /     \       /  \
    1       4     9   11
           /
          3

这样,您可以构造一棵树,并最终找到其后遍历遍历,即:1、3、4、2、9、11、10、7、6