繁体   English   中英

预订到订单后的遍历

[英]Pre-order to post-order traversal

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

您将获得树的预顺序遍历,该结构通过以下方式构造:输出,遍历左,遍历右。

由于后序遍历来自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. 在后序中遍历生成的树以获得与给定的预订遍历相关联的后序遍历。

使用上述算法,与问题中的预先遍历相关联的后序遍历是:1,3,4,2,9,11,10,7,6。将其留作练习。

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

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

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

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

根据Ondrej Tucny的回答。 仅适用于BST
例:

     20  
    /  \  
   10  30  
   /\    \  
  6  15   35  

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

对于BST,在预先遍历遍历; 数组的第一个元素是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;
 }

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

这是在python中对postorder遍历进行预订的代码。 我正在构建一棵树,所以你可以找到任何类型的遍历

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)

您将获得预订遍历结果。 然后将值放到合适的二叉搜索树中,并按照获得的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))

输出:

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

说明

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

  • first:小于root的元素,属于root的左子树
  • 第二:大于root的元素,属于root的右子树

然后我们只是递归地调用两个子树上的函数(它仍然是预先订购的)然后链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的右边部分。预定数组中的所有元素都比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;
} 

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

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

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

点 - :

  1. 第一个系列将是root(父),即6

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

这是完整的代码)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM