📜  从预遍历中查找BST的后遍历

📅  最后修改于: 2021-05-24 22:01:22             🧑  作者: Mango

给定一个表示BST的遍历遍历的数组,请打印其后遍历。

例子:

Input : 40 30 35 80 100
Output : 35 30 100 80 40

Input : 40 30 32 35 80 90 100 120
Output : 35 32 30 120 100 90 80 40

先决条件:根据给定的遍历构造BST

简单方法:一个简单的解决方案是,首先按照给定的遍历结构构造BST,如本文所述。构造完树后,对其执行后置遍历。

高效的方法:一种有效的方法是在不构造树的情况下查找后遍历。想法是遍历给定的预序列,并保持当前元素应位于的范围。这是为了确保始终满足BST属性。最初,范围设置为{minval = INT_MIN,maxval = INT_MAX}。在预遍历中,第一个元素始终是根,并且肯定会在初始范围内。因此,存储预订数组的第一个元素。在后序遍历中,首先打印左和右子树,然后打印根数据。因此,首先执行对左和右子树的递归调用,然后打印root的值。对于左侧子树,范围更新为{minval,root-> data},对于右侧子树,范围更新为{root-> data,maxval}。如果当前的预排序数组元素不在为其指定的范围内,则它不属于当前的子树,请从递归调用返回,直到找不到该元素的正确位置为止。

下面是上述方法的实现:

C++
// C++ program for finding postorder
// traversal of BST from preorder traversal
#include 
using namespace std;
 
// Function to find postorder traversal from
// preorder traversal.
void findPostOrderUtil(int pre[], int n, int minval,
                       int maxval, int& preIndex)
{
 
    // If entire preorder array is traversed then
    // return as no more element is left to be
    // added to post order array.
    if (preIndex == n)
        return;
 
    // If array element does not lie in range specified,
    // then it is not part of current subtree.
    if (pre[preIndex] < minval || pre[preIndex] > maxval) {
        return;
    }
 
    // Store current value, to be printed later, after
    // printing left and right subtrees. Increment
    // preIndex to find left and right subtrees,
    // and pass this updated value to recursive calls.
    int val = pre[preIndex];
    preIndex++;
 
    // All elements with value between minval and val
    // lie in left subtree.
    findPostOrderUtil(pre, n, minval, val, preIndex);
 
    // All elements with value between val and maxval
    // lie in right subtree.
    findPostOrderUtil(pre, n, val, maxval, preIndex);
 
    cout << val << " ";
}
 
// Function to find postorder traversal.
void findPostOrder(int pre[], int n)
{
 
    // To store index of element to be
    // traversed next in preorder array.
    // This is passed by reference to
    // utility function.
    int preIndex = 0;
 
    findPostOrderUtil(pre, n, INT_MIN, INT_MAX, preIndex);
}
 
// Driver code
int main()
{
    int pre[] = { 40, 30, 35, 80, 100 };
 
    int n = sizeof(pre) / sizeof(pre[0]);
 
    // Calling function
    findPostOrder(pre, n);
    return 0;
}


Java
// Java program for finding postorder
// traversal of BST from preorder traversal
 
import java.util.*;
 
class Solution {
    static class INT {
        int data;
        INT(int d) { data = d; }
    }
 
    // Function to find postorder traversal from
    // preorder traversal.
    static void findPostOrderUtil(int pre[], int n,
                                  int minval, int maxval,
                                  INT preIndex)
    {
 
        // If entire preorder array is traversed then
        // return as no more element is left to be
        // added to post order array.
        if (preIndex.data == n)
            return;
 
        // If array element does not lie in range specified,
        // then it is not part of current subtree.
        if (pre[preIndex.data] < minval
            || pre[preIndex.data] > maxval) {
            return;
        }
 
        // Store current value, to be printed later, after
        // printing left and right subtrees. Increment
        // preIndex to find left and right subtrees,
        // and pass this updated value to recursive calls.
        int val = pre[preIndex.data];
        preIndex.data++;
 
        // All elements with value between minval and val
        // lie in left subtree.
        findPostOrderUtil(pre, n, minval, val, preIndex);
 
        // All elements with value between val and maxval
        // lie in right subtree.
        findPostOrderUtil(pre, n, val, maxval, preIndex);
 
        System.out.print(val + " ");
    }
 
    // Function to find postorder traversal.
    static void findPostOrder(int pre[], int n)
    {
 
        // To store index of element to be
        // traversed next in preorder array.
        // This is passed by reference to
        // utility function.
        INT preIndex = new INT(0);
 
        findPostOrderUtil(pre, n, Integer.MIN_VALUE,
                          Integer.MAX_VALUE, preIndex);
    }
 
    // Driver code
    public static void main(String args[])
    {
        int pre[] = { 40, 30, 35, 80, 100 };
 
        int n = pre.length;
 
        // Calling function
        findPostOrder(pre, n);
    }
}
 
// This code is contributed
// by Arnab Kundu


Python3
"""Python3 program for finding postorder
traversal of BST from preorder traversal"""
 
INT_MIN = -2**31
INT_MAX = 2**31
 
# Function to find postorder traversal
# from preorder traversal.
 
 
def findPostOrderUtil(pre, n, minval,
                      maxval, preIndex):
 
    # If entire preorder array is traversed
    # then return as no more element is left
    # to be added to post order array.
    if (preIndex[0] == n):
        return
 
    # If array element does not lie in
    # range specified, then it is not
    # part of current subtree.
    if (pre[preIndex[0]] < minval or
            pre[preIndex[0]] > maxval):
        return
 
    # Store current value, to be printed later,
    # after printing left and right subtrees.
    # Increment preIndex to find left and right
    # subtrees, and pass this updated value to
    # recursive calls.
    val = pre[preIndex[0]]
    preIndex[0] += 1
 
    # All elements with value between minval
    # and val lie in left subtree.
    findPostOrderUtil(pre, n, minval,
                      val, preIndex)
 
    # All elements with value between val
    # and maxval lie in right subtree.
    findPostOrderUtil(pre, n, val,
                      maxval, preIndex)
 
    print(val, end=" ")
 
# Function to find postorder traversal.
 
 
def findPostOrder(pre, n):
 
    # To store index of element to be
    # traversed next in preorder array.
    # This is passed by reference to
    # utility function.
    preIndex = [0]
 
    findPostOrderUtil(pre, n, INT_MIN,
                      INT_MAX, preIndex)
 
 
# Driver Code
if __name__ == '__main__':
    pre = [40, 30, 35, 80, 100]
 
    n = len(pre)
 
    # Calling function
    findPostOrder(pre, n)
 
# This code is contributed by
# SHUBHAMSINGH10


C#
// C# program for finding postorder
// traversal of BST from preorder traversal
using System;
 
class GFG {
    public class INT {
        public int data;
        public INT(int d) { data = d; }
    }
 
    // Function to find postorder traversal from
    // preorder traversal.
    public static void findPostOrderUtil(int[] pre, int n,
                                         int minval,
                                         int maxval,
                                         INT preIndex)
    {
 
        // If entire preorder array is traversed
        // then return as no more element is left
        // to be added to post order array.
        if (preIndex.data == n) {
            return;
        }
 
        // If array element does not lie in
        // range specified, then it is not
        // part of current subtree.
        if (pre[preIndex.data] < minval
            || pre[preIndex.data] > maxval) {
            return;
        }
 
        // Store current value, to be printed
        // later, after printing left and right
        // subtrees. Increment preIndex to find
        // left and right subtrees, and pass this
        // updated value to recursive calls.
        int val = pre[preIndex.data];
        preIndex.data++;
 
        // All elements with value between
        // minval and val lie in left subtree.
        findPostOrderUtil(pre, n, minval, val, preIndex);
 
        // All elements with value between
        // val and maxval lie in right subtree.
        findPostOrderUtil(pre, n, val, maxval, preIndex);
 
        Console.Write(val + " ");
    }
 
    // Function to find postorder traversal.
    public static void findPostOrder(int[] pre, int n)
    {
 
        // To store index of element to be
        // traversed next in preorder array.
        // This is passed by reference to
        // utility function.
        INT preIndex = new INT(0);
 
        findPostOrderUtil(pre, n, int.MinValue,
                          int.MaxValue, preIndex);
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        int[] pre = new int[] { 40, 30, 35, 80, 100 };
 
        int n = pre.Length;
 
        // Calling function
        findPostOrder(pre, n);
    }
}
 
// This code is contributed by Shrikant13


C++
#include 
using namespace std;
 
void getPostOrderBST(int pre[], int N)
{
    int pivotPoint = 0;
 
    // Run loop from 1 to length of pre
    for(int i = 1; i < N; i++)
    {
        if (pre[0] <= pre[i])
        {
            pivotPoint = i;
            break;
        }
    }
 
    // Print from pivot length -1 to zero
    for(int i = pivotPoint - 1; i > 0; i--)
    {
        cout << pre[i] << " ";
    }
 
    // Print from end to pivot length
    for(int i = N - 1; i >= pivotPoint; i--)
    {
        cout << pre[i] << " ";
    }
    cout << pre[0];
}
 
// Driver Code
int main()
{
    int pre[] = { 40, 30, 32, 35,
                  80, 90, 100, 120 };
    int N = 8;
     
    getPostOrderBST(pre, N);
     
    return 0;
}
 
// This code is contributed by RohitOberoi


Java
import java.io.*;
 
class GFG {
     
    public void getPostOrderBST(int pre[])
    {
        int pivotPoint = 0;
       
        // run loop from 1 to length of pre
        for (int i = 1; i < pre.length; i++)
        {
            if (pre[0] <= pre[i])
            {
                pivotPoint = i;
                break;
            }
        }
       
        // print from pivot length -1 to zero
        for (int i = pivotPoint - 1; i > 0; i--)
        {
            System.out.print(pre[i] + " ");
        }
       
        // print from end to pivot length
        for (int i = pre.length - 1; i >= pivotPoint; i--)
        {
            System.out.print(pre[i] + " ");
        }
        System.out.print(pre[0]);
    }
   
    // Driver Code
    public static void main(String[] args)
    {
        GFG obj = new GFG();
        int pre[] = { 40, 30, 32, 35, 80, 90, 100, 120 };
        obj.getPostOrderBST(pre);
    }
}


Python3
def getPostOrderBST(pre, N):
    pivotPoint = 0
 
    # Run loop from 1 to length of pre
    for i in range(1, N):
        if (pre[0] <= pre[i]):
            pivotPoint= i
            break
 
    # Prfrom pivot length -1 to zero
    for i in range(pivotPoint - 1, 0, -1):
        print(pre[i], end = " ")
 
    # Prfrom end to pivot length
    for i in range(N - 1, pivotPoint - 1, -1):
        print(pre[i], end = " ")
    print(pre[0])
 
# Driver Code
if __name__ == '__main__':
    pre = [40, 30, 32, 35,80, 90, 100, 120]
    N = 8
 
    getPostOrderBST(pre, N)
 
# This code is contributed by mohit kumar 29


C#
using System;
 
class GFG{
     
public void getPostOrderBST(int []pre)
{
    int pivotPoint = 0;
     
    // Run loop from 1 to length of pre
    for(int i = 1; i < pre.Length; i++)
    {
        if (pre[0] <= pre[i])
        {
            pivotPoint = i;
            break;
        }
    }
 
    // Print from pivot length -1 to zero
    for(int i = pivotPoint - 1; i > 0; i--)
    {
        Console.Write(pre[i] + " ");
    }
 
    // Print from end to pivot length
    for(int i = pre.Length - 1;
            i >= pivotPoint; i--)
    {
        Console.Write(pre[i] + " ");
    }
    Console.Write(pre[0]);
}
 
// Driver Code
public static void Main(String[] args)
{
    GFG obj = new GFG();
    int []pre = { 40, 30, 32, 35,
                  80, 90, 100, 120 };
                   
    obj.getPostOrderBST(pre);
}
}
 
// This code is contributed by shivanisinghss2110


Javascript


输出
35 30 100 80 40

时间复杂度: O(N),其中N是节点数。
辅助空间: O(N)(函数调用堆栈的大小)

另一种方法

在BST的预遍历中,第一个元素是树的根元素。遍历给定的BST遍历,并将每个元素与数组的第一个元素进行比较,直到索引小于第一个元素的索引为止。将索引的值存储在名为“ Pivot”的变量中。从’Pivot’索引到索引1的预定数组的打印元素。从’array,length’索引– 1到’Pivot’索引+ 1的预定数组的打印元素。打印预定数组的第一个元素。

下面是上述方法的Java实现:

C++

#include 
using namespace std;
 
void getPostOrderBST(int pre[], int N)
{
    int pivotPoint = 0;
 
    // Run loop from 1 to length of pre
    for(int i = 1; i < N; i++)
    {
        if (pre[0] <= pre[i])
        {
            pivotPoint = i;
            break;
        }
    }
 
    // Print from pivot length -1 to zero
    for(int i = pivotPoint - 1; i > 0; i--)
    {
        cout << pre[i] << " ";
    }
 
    // Print from end to pivot length
    for(int i = N - 1; i >= pivotPoint; i--)
    {
        cout << pre[i] << " ";
    }
    cout << pre[0];
}
 
// Driver Code
int main()
{
    int pre[] = { 40, 30, 32, 35,
                  80, 90, 100, 120 };
    int N = 8;
     
    getPostOrderBST(pre, N);
     
    return 0;
}
 
// This code is contributed by RohitOberoi

Java

import java.io.*;
 
class GFG {
     
    public void getPostOrderBST(int pre[])
    {
        int pivotPoint = 0;
       
        // run loop from 1 to length of pre
        for (int i = 1; i < pre.length; i++)
        {
            if (pre[0] <= pre[i])
            {
                pivotPoint = i;
                break;
            }
        }
       
        // print from pivot length -1 to zero
        for (int i = pivotPoint - 1; i > 0; i--)
        {
            System.out.print(pre[i] + " ");
        }
       
        // print from end to pivot length
        for (int i = pre.length - 1; i >= pivotPoint; i--)
        {
            System.out.print(pre[i] + " ");
        }
        System.out.print(pre[0]);
    }
   
    // Driver Code
    public static void main(String[] args)
    {
        GFG obj = new GFG();
        int pre[] = { 40, 30, 32, 35, 80, 90, 100, 120 };
        obj.getPostOrderBST(pre);
    }
}

Python3

def getPostOrderBST(pre, N):
    pivotPoint = 0
 
    # Run loop from 1 to length of pre
    for i in range(1, N):
        if (pre[0] <= pre[i]):
            pivotPoint= i
            break
 
    # Prfrom pivot length -1 to zero
    for i in range(pivotPoint - 1, 0, -1):
        print(pre[i], end = " ")
 
    # Prfrom end to pivot length
    for i in range(N - 1, pivotPoint - 1, -1):
        print(pre[i], end = " ")
    print(pre[0])
 
# Driver Code
if __name__ == '__main__':
    pre = [40, 30, 32, 35,80, 90, 100, 120]
    N = 8
 
    getPostOrderBST(pre, N)
 
# This code is contributed by mohit kumar 29

C#

using System;
 
class GFG{
     
public void getPostOrderBST(int []pre)
{
    int pivotPoint = 0;
     
    // Run loop from 1 to length of pre
    for(int i = 1; i < pre.Length; i++)
    {
        if (pre[0] <= pre[i])
        {
            pivotPoint = i;
            break;
        }
    }
 
    // Print from pivot length -1 to zero
    for(int i = pivotPoint - 1; i > 0; i--)
    {
        Console.Write(pre[i] + " ");
    }
 
    // Print from end to pivot length
    for(int i = pre.Length - 1;
            i >= pivotPoint; i--)
    {
        Console.Write(pre[i] + " ");
    }
    Console.Write(pre[0]);
}
 
// Driver Code
public static void Main(String[] args)
{
    GFG obj = new GFG();
    int []pre = { 40, 30, 32, 35,
                  80, 90, 100, 120 };
                   
    obj.getPostOrderBST(pre);
}
}
 
// This code is contributed by shivanisinghss2110

Java脚本


输出
35 32 30 120 100 90 80 40

时间复杂度: O(n)
辅助空间: O(1)