前序到后序的遍历

发布于 2024-10-09 22:04:57 字数 49 浏览 0 评论 0原文

如果二叉搜索树的前序遍历为6,2,1,4,3,7,10,9,11,如何得到后序遍历?

If the pre-order traversal of a binary search tree is 6, 2, 1, 4, 3, 7, 10, 9, 11, how to get the post-order traversal?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

戴着白色围巾的女孩 2024-10-16 22:04:57

给定树的前序遍历,它是通过以下操作构建的:输出、向左遍历、向右遍历。

由于后序遍历来自二叉搜索树,因此可以通过对数字进行排序,从后序遍历推导出中序遍历(左遍历、输出、右遍历)。在您的示例中,中序遍历是 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。到达那里作为练习。

You are given the pre-order traversal of the tree, which is constructed by doing: output, traverse left, traverse right.

As the post-order traversal comes from a BST, you can deduce the in-order traversal (traverse left, output, traverse right) from the post-order traversal by sorting the numbers. In your example, the in-order traversal is 1, 2, 3, 4, 6, 7, 9, 10, 11.

From two traversals we can then construct the original tree. Let's use a simpler example for this:

  • Pre-order: 2, 1, 4, 3
  • In-order: 1, 2, 3, 4

The pre-order traversal gives us the root of the tree as 2. The in-order traversal tells us 1 falls into the left sub-tree and 3, 4 falls into the right sub-tree. The structure of the left sub-tree is trivial as it contains a single element. The right sub-tree's pre-order traversal is deduced by taking the order of the elements in this sub-tree from the original pre-order traversal: 4, 3. From this we know the root of the right sub-tree is 4 and from the in-order traversal (3, 4) we know that 3 falls into the left sub-tree. Our final tree looks like this:

  2
 / \
1   4
   /
  3

With the tree structure, we can get the post-order traversal by walking the tree: traverse left, traverse right, output. For this example, the post-order traversal is 1, 3, 4, 2.

To generalise the algorithm:

  1. The first element in the pre-order traversal is the root of the tree. Elements less than the root form the left sub-tree. Elements greater than the root form the right sub-tree.
  2. Find the structure of the left and right sub-trees using step 1 with a pre-order traversal that consists of the elements we worked out to be in that sub-tree placed in the order they appear in the original pre-order traversal.
  3. Traverse the resulting tree in post-order to get the post-order traversal associated with the given pre-order traversal.

Using the above algorithm, the post-order traversal associated with the pre-order traversal in the question is: 1, 3, 4, 2, 9, 11, 10, 7, 6. Getting there is left as an exercise.

弱骨蛰伏 2024-10-16 22:04:57

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

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

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

为了按后序输出树,应用了递归和输出重新排序。这个任务就留给了读者。

Pre-order = outputting the values of a binary tree in the order of the current node, then the left subtree, then the right subtree.

Post-order = outputting the values of a binary tree in the order of the left subtree, then the right subtree, the the current node.

In a binary search tree, the values of all nodes in the left subtree are less than the value of the current node; and alike for the right subtree. Hence if you know the start of a pre-order dump of a binary search tree (i.e. its root node's value), you can easily decompose the whole dump into the root node value, the values of the left subtree's nodes, and the values of the right subtree's nodes.

To output the tree in post-order, recursion and output reordering is applied. This task is left upon the reader.

甜宝宝 2024-10-16 22:04:57

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

     20  
    /  \  
   10  30  
   /\    \  
  6  15   35  

预购 = 20 10 6 15 30 35
Post = 6 15 10 35 30 20

对于 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;
 }

如有错误请指正。

Based on Ondrej Tucny's answer. Valid for BST only
example:

     20  
    /  \  
   10  30  
   /\    \  
  6  15   35  

Preorder = 20 10 6 15 30 35
Post = 6 15 10 35 30 20

For a BST, In Preorder traversal; first element of array is 20. This is the root of our tree. All numbers in array which are lesser than 20 form its left subtree and greater numbers form right subtree.

//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;
 }

Please correct me if there is any mistake.

Oo萌小芽oO 2024-10-16 22:04:57

您将获得预序遍历结果。然后将这些值放入合适的二叉搜索树中,并遵循后序遍历算法获得 BST。

you are given the pre-order traversal results. then put the values to a suitable binary search tree and just follow the post-order traversal algorithm for the obtained BST.

勿忘初心 2024-10-16 22:04:57

这是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)

This is the code of preorder to postorder traversal in python.
I am constructing a tree so you can find any type of traversal

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)
生生漫 2024-10-16 22:04:57

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

我们不必重建 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的元素,属于根的左子树;
  • second:大于root的元素>,属于根的右子树

然后我们只需在两个子树(仍然处于前序状态)上递归调用该函数,然后链接left + right + root(这是后序) -命令)。

I know this is old but there is a better solution.

We don't have to reconstruct a BST to get the post-order from the pre-order.

Here is a simple python code that does it recursively:

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

Output:

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

Explanation:

We know that we are in pre-order. This means that the root is at the index 0 of the list of the values in the BST. And we know that the elements following the root are:

  • first: the elements less than the root, which belong to the left subtree of the root
  • second: the elements greater than the root, which belong to the right subtree of the root

We then just call recursively the function on both subtrees (which still are in pre-order) and then chain left + right + root (which is the post-order).

枕头说它不想醒 2024-10-16 22:04:57

如果您已收到预购订单并且您想将其转换为后购订单。那么你应该记住,在 BST 中,顺序总是按升序给出数字。因此,你既有中序也有预序来构造一棵树。

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

中序:1, 2, 3, 4, 6, 7, 9, 10, 11 code>

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

If you have been given preorder and you want to convert it into postorder. Then you should remember that in a BST in order always give numbers in ascending order.Thus you have both Inorder as well as the preorder to construct a tree.

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

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

And its postorder: 1 3 4 2 9 11 10 7 6

厌味 2024-10-16 22:04:57

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

#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;
} 

Here pre-order traversal of a binary search tree is given in array.
So the 1st element of pre-order array will root of BST.We will find the left part of BST and right part of BST.All the element in pre-order array is lesser than root will be left node and All the element in pre-order array is greater then root will be right node.

#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;
} 
孤独患者 2024-10-16 22:04:57

据我们所知,预购遵循父、左、右系列。

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

您的问题由系列 6、2、1、4、3、7、10、9、11

点组成 -:

  1. 系列的第一个数字将是根(父级),即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

As we Know preOrder follow parent, left, right series.

In order to construct tree we need to follow few basic steps-:

your question consist of series 6, 2,1,4,3,7,10,9,11

points-:

  1. First number of series will be root(parent) i.e 6

2.Find the number which is greater than 6 so in this series 7 is first greater number in this series so right node will be starting from here and left to this number(7) is your left subtrees.

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

3.same way follow the basic rule of BST i.e left,root,right

the series of post order will be L, R, N i.e. 1,3,4,2,9,11,10,7,6

救赎№ 2024-10-16 22:04:57

这是完整代码)

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

Here is full code )

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())
单调的奢华 2024-10-16 22:04:57

由于它是二叉搜索树,因此中序遍历将始终是已排序的元素。 (left < root < right)

所以,你可以很容易地先写出它的中序遍历结果,即: 1,2,3,4,6,7,9,10,11

给定 Pre-order : 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

第五步:下一个根为10:

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

这样,你可以构造一棵树,最后找到它的后序遍历,即:1,3,4,2,9,11,10 , 7, 6

Since, it is a binary search tree, the inorder traversal will be always be the sorted elements. (left < root < right)

so, you can easily write its in-order traversal results first, which is : 1,2,3,4,6,7,9,10,11

given Pre-order : 6, 2, 1, 4, 3, 7, 10, 9, 11

In-order : left, root, right
Pre-order : root, left, right
Post-order : left, right, root

now, we got from pre-order, that root is 6.

now, using in-order and pre-order results:
Step 1:

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

Step 2: next root is, using in-order traversal, 2:

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

Step 3: Similarly, next root is 4:

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

Step 4: next root is 3, but no other element is remaining to be fit in the child tree for "3". Considering next root as 7 now,

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

Step 5: Next root is 10 :

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

This is how, you can construct a tree, and finally find its post-order traversal, which is : 1, 3, 4, 2, 9, 11, 10, 7, 6

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文