Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 前序到后序遍历_Algorithm_Data Structures_Tree Traversal_Binary Search Tree - Fatal编程技术网

Algorithm 前序到后序遍历

Algorithm 前序到后序遍历,algorithm,data-structures,tree-traversal,binary-search-tree,Algorithm,Data Structures,Tree Traversal,Binary Search Tree,如果二叉搜索树的预序遍历是6、2、1、4、3、7、10、9、11,如何获得后序遍历?预序=按当前节点、左子树、右子树的顺序输出二叉树的值 Post order=按左子树、右子树和当前节点的顺序输出二叉树的值 在二叉搜索树中,左子树中所有节点的值都小于当前节点的值;对于正确的子树也是如此。因此,如果知道二叉搜索树的预排序转储的开始(即其根节点的值),则可以轻松地将整个转储分解为根节点值、左子树节点的值和右子树节点的值 要按后序输出树,将应用递归和输出重新排序。此任务留给读者。您将获得树的预顺序遍历

如果二叉搜索树的预序遍历是6、2、1、4、3、7、10、9、11,如何获得后序遍历?

预序=按当前节点、左子树、右子树的顺序输出二叉树的值

Post order=按左子树、右子树和当前节点的顺序输出二叉树的值

在二叉搜索树中,左子树中所有节点的值都小于当前节点的值;对于正确的子树也是如此。因此,如果知道二叉搜索树的预排序转储的开始(即其根节点的值),则可以轻松地将整个转储分解为根节点值、左子树节点的值和右子树节点的值


要按后序输出树,将应用递归和输出重新排序。此任务留给读者。

您将获得树的预顺序遍历,它是通过以下操作构建的:输出、左遍历、右遍历

由于后序遍历来自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和预顺序遍历查找左、右子树的结构,预顺序遍历由我们计算出的元素组成,这些元素按它们在原始预顺序遍历中出现的顺序放置在该子树中
  • 按后序遍历生成的树,以获得与给定的前序遍历关联的后序遍历

  • 使用上述算法,与问题中的前序遍历关联的后序遍历是:1、3、4、2、9、11、10、7、6。到达那里只是一种练习。

    基于昂德雷·图尼的回答。仅对BST有效
    例如:

         20  
        /  \  
       10  30  
       /\    \  
      6  15   35  
    
    预订单=201061535
    邮政=61510353020

    对于BST,在前序遍历中;数组的第一个元素是20。这是我们树的根。数组中小于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;
     }
    
    //N=BST中的节点数(遍历数组的大小)
    int post[N]={0};
    int i=0;
    无效预结算(int pre[],int l,int r){
    if(l==r){post[i++]=pre[l];return;}
    //pre[l]是根
    //将数组分为较小的数和较大的数,然后递归调用此函数
    对于(int j=l+1;jpre[l])
    打破
    PretoPost(a,l+1,j-1);//添加左节点
    PretoPost(a,j,r);//添加右节点
    //根最终应该消失
    post[i++]=pre[l];
    返回;
    }
    

    如果有任何错误,请更正。

    您将获得预排序遍历结果。然后将值放入合适的二叉搜索树中,只需按照获得的BST的后序遍历算法进行操作。

    我知道这很旧,但有更好的解决方案

    我们不必重建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))
    
    说明

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

    • 第一:小于
      的元素,它们属于根的左子树
    • 第二:大于
      根的元素,它们属于根的右子树

    然后,我们只需递归调用两个子树上的函数(仍然是预序),然后调用chain
    left+right+root
    (即后序)。

    如果您已获得预序,并且希望将其转换为后序。然后你应该记住,在BST中,顺序总是以升序给出数字。因此,你既有顺序也有前序来构造一棵树

    前序:
    6,2,1,4,3,7,10,9,11

    顺序:
    1,2,3,4,6,7,9,10,11


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

    这里以数组形式给出了二叉搜索树的前序遍历。 因此,预排序数组的第一个元素将是BST的根。我们将找到BST的左部分和BST的右部分。预排序数组中的所有元素小于根将是左节点,预排序数组中的所有元素大于根将是右节点

    #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;
    } 
    
    #包括
    使用名称空间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指数=-1;
    
    对于(inti=l;i我们知道,前序跟随父、左、右序列

    #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;
    } 
    
                          6
                        /   \
                       2     7
                     /  \     \
                    1    4     10
                         /     / \
                         3     9  11
    
    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)
    
    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())
    
                 6
                / \
               /   \
              /     \
             /       \
       {1,2,3,4}  {7,9,10,11}
    
                 6
                / \
               /   \
              /     \
             /       \
            2  {7,9,10,11}
           / \
          /   \
         /     \
        1    {3,4}
    
                 6
                / \
               /   \
              /     \
             /       \
            2  {7,9,10,11}
           / \
          /   \
         /     \
        1       4
               /
              3
    
                 6
                / \
               /   \
              /     \
             /       \
            2         7
           / \         \
          /   \       {9,10,11}
         /     \
        1       4
               /
              3
    
                 6
                / \
               /   \
              /     \
             /       \
            2         7
           / \         \
          /   \         10
         /     \       /  \
        1       4     9   11
               /
              3