Find postorder traversal of BST from preorder traversal in C++

In this problem we are given an array preOrder[] that represents the preorder traversal of the binary search tree. Our task is to Find postorder traversal of BST from preorder traversal.

Let’s take an example to understand the problem,

Input

preOrder[] = {5, 2, 4, 7, 12}

Output

{4, 2, 12, 7, 5}

Solution Approach

A simple solution to the problem is to create a BST from the given preorder traversal. And then do postorder traversal of the tree. This solution is Ok but a more effective solution is,

We will traverse the preorder array with a limit on values to separate values of left and right subtree.

The order for traversal is −

preOrder : Root -> Left -> Right
postOrder : Left -> Right -> Root

For the first element in preorder which is the root element. For this, the limit is {INT_MIN, Root}. Then traverse the preorder array and first element and swap all elements in limit with the last value of the limit. Similarly, we will do this for right subtree and add the root at the end.

Program to illustrate the working of our solution,

Example

Live Demo

#include <iostream>
using namespace std;
void findPostOrderTraversalRec(int pre[], int n, int lowerLimit, int
upperLimit, int& index){
if (index == n)
return;
if (pre[index] < lowerLimit || pre[index] > upperLimit)
return;
int currNode = pre[index];
index++;
findPostOrderTraversalRec(pre, n, lowerLimit, currNode, index);
findPostOrderTraversalRec(pre, n, currNode, upperLimit, index);
cout<<currNode<<" ";
}
void findPostOrderTraversalFromPreOrder(int pre[], int n){
int index = 0;
findPostOrderTraversalRec(pre, n, -1000, 1000, index);
}
int main(){
int pre[] = { 5, 2, 4, 7, 12 };
int n = sizeof(pre) / sizeof(pre[0]);
cout<<"PreOrder Traversal : \t";
for(int i = 0; i < n ; i++)
cout<<pre[i]<<" ";
cout<<endl<<"Post Order Traversal : \t";
findPostOrderTraversalFromPreOrder(pre, n);
return 0;
}

Output

PreOrder Traversal − 5 2 4 7 12
Post Order Traversal − 4 2 12 7 5

One more method to solve the problem is using iteration. As we know that the preorder in root -> left -> right and postOrder is left -> right -> root. This can be calculated using a loop and calculating the pivot element which is where the last element of the left element is. Using this we will print the left first, then the right and then the root.

The pivot is found by finding the index of a greater element smaller that root.

Program to illustrate the working of our solution,

Example

Live Demo

#include <iostream>
using namespace std;
void findPostOrderTraversalFromPreOrder(int pre[], int n){
int pivot = 0;
for(int i = 1; i < n; i++){
if (pre[0] <= pre[i]) {
pivot = i;
break;
}
}
for(int i = pivot - 1; i > 0; i--){
cout << pre[i] << " ";
}
for(int i = n - 1; i >= pivot; i--) {
cout << pre[i] << " ";
}
cout << pre[0];
}
int main(){
int pre[] = { 5, 2, 4, 7, 12 };
int n = sizeof(pre) / sizeof(pre[0]);
cout<<"PreOrder Traversal : \t";
for(int i = 0; i < n ; i++)
cout<<pre[i]<<" ";
cout<<endl<<"Post Order Traversal : \t";
findPostOrderTraversalFromPreOrder(pre, n);
return 0;
}

Output

PreOrder Traversal − 5 2 4 7 12
Post Order Traversal − 4 2 12 7 5

Updated on: 16-Mar-2021

1K+ Views