Construct a Binary Tree from Postorder and Inorder

Given Postorder and Inorder traversals, construct the tree.
Examples: 
 

Input: 
in[]   = {2, 1, 3}
post[] = {2, 3, 1}

Output: Root of below tree
      1
    /   \
   2     3 


Input: 
in[]   = {4, 8, 2, 5, 1, 6, 3, 7}
post[] = {8, 4, 5, 2, 6, 7, 3, 1} 

Output: Root of below tree
          1
       /     \
     2        3
   /    \   /   \
  4     5   6    7
    \
      8

We have already discussed construction of tree from Inorder and Preorder traversals. The idea is similar.
Let us see the process of constructing tree from in[] = {4, 8, 2, 5, 1, 6, 3, 7} and post[] = {8, 4, 5, 2, 6, 7, 3, 1} 
1) We first find the last node in post[]. The last node is “1”, we know this value is root as root always appear in the end of postorder traversal.
2) We search “1” in in[] to find left and right subtrees of root. Everything on left of “1” in in[] is in left subtree and everything on right is in right subtree. 

         1
       /    \
[4, 8, 2, 5]   [6, 3, 7] 

3) We recur the above process for following two. 
….b) Recur for in[] = {6, 3, 7} and post[] = {6, 7, 3} 
…….Make the created tree as right child of root. 
….a) Recur for in[] = {4, 8, 2, 5} and post[] = {8, 4, 5, 2}. 
…….Make the created tree as left child of root.
Below is the implementation of above idea. One important observation is, we recursively call for right subtree before left subtree as we decrease index of postorder index whenever we create a new node. 
 

filter_none

edit
close

play_arrow

link
brightness_4
code

/* C++ program to construct tree using inorder and
   postorder traversals */
#include <bits/stdc++.h>
  
using namespace std;
  
/* A binary tree node has data, pointer to left
   child and a pointer to right child */
struct Node {
    int data;
    Node *left, *right;
};
  
// Utility function to create a new node
Node* newNode(int data);
  
/* Prototypes for utility functions */
int search(int arr[], int strt, int end, int value);
  
/* Recursive function to construct binary of size n
   from  Inorder traversal in[] and Postorder traversal
   post[].  Initial values of inStrt and inEnd should
   be 0 and n -1.  The function doesn't do any error
   checking for cases where inorder and postorder
   do not form a tree */
Node* buildUtil(int in[], int post[], int inStrt,
                int inEnd, int* pIndex)
{
    // Base case
    if (inStrt > inEnd)
        return NULL;
  
    /* Pick current node from Postorder traversal using
       postIndex and decrement postIndex */
    Node* node = newNode(post[*pIndex]);
    (*pIndex)--;
  
    /* If this node has no children then return */
    if (inStrt == inEnd)
        return node;
  
    /* Else find the index of this node in Inorder
       traversal */
    int iIndex = search(in, inStrt, inEnd, node->data);
  
    /* Using index in Inorder traversal, construct left and
       right subtress */
    node->right = buildUtil(in, post, iIndex + 1, inEnd, pIndex);
    node->left = buildUtil(in, post, inStrt, iIndex - 1, pIndex);
  
    return node;
}
  
// This function mainly initializes index of root
// and calls buildUtil()
Node* buildTree(int in[], int post[], int n)
{
    int pIndex = n - 1;
    return buildUtil(in, post, 0, n - 1, &pIndex);
}
  
/* Function to find index of value in arr[start...end]
   The function assumes that value is postsent in in[] */
int search(int arr[], int strt, int end, int value)
{
    int i;
    for (i = strt; i <= end; i++) {
        if (arr[i] == value)
            break;
    }
    return i;
}
  
/* Helper function that allocates a new node */
Node* newNode(int data)
{
    Node* node = (Node*)malloc(sizeof(Node));
    node->data = data;
    node->left = node->right = NULL;
    return (node);
}
  
/* This funtcion is here just to test  */
void preOrder(Node* node)
{
    if (node == NULL)
        return;
    printf("%d ", node->data);
    preOrder(node->left);
    preOrder(node->right);
}
  
// Driver code
int main()
{
    int in[] = { 4, 8, 2, 5, 1, 6, 3, 7 };
    int post[] = { 8, 4, 5, 2, 6, 7, 3, 1 };
    int n = sizeof(in) / sizeof(in[0]);
  
    Node* root = buildTree(in, post, n);
  
    cout << "Preorder of the constructed tree : \n";
    preOrder(root);
  
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to construct a tree using inorder
// and postorder traversals
  
/* A binary tree node has data, pointer to left
   child and a pointer to right child */
class Node {
    int data;
    Node left, right;
  
    public Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}
  
// Class Index created to implement pass by reference of Index
class Index {
    int index;
}
  
class BinaryTree {
    /* Recursive function to construct binary of size n
       from  Inorder traversal in[] and Postrder traversal
       post[].  Initial values of inStrt and inEnd should
       be 0 and n -1.  The function doesn't do any error
       checking for cases where inorder and postorder
       do not form a tree */
    Node buildUtil(int in[], int post[], int inStrt,
                   int inEnd, Index pIndex)
    {
        // Base case
        if (inStrt > inEnd)
            return null;
  
        /* Pick current node from Postrder traversal using
           postIndex and decrement postIndex */
        Node node = new Node(post[pIndex.index]);
        (pIndex.index)--;
  
        /* If this node has no children then return */
        if (inStrt == inEnd)
            return node;
  
        /* Else find the index of this node in Inorder
           traversal */
        int iIndex = search(in, inStrt, inEnd, node.data);
  
        /* Using index in Inorder traversal, construct left and
           right subtress */
        node.right = buildUtil(in, post, iIndex + 1, inEnd, pIndex);
        node.left = buildUtil(in, post, inStrt, iIndex - 1, pIndex);
  
        return node;
    }
  
    // This function mainly initializes index of root
    // and calls buildUtil()
    Node buildTree(int in[], int post[], int n)
    {
        Index pIndex = new Index();
        pIndex.index = n - 1;
        return buildUtil(in, post, 0, n - 1, pIndex);
    }
  
    /* Function to find index of value in arr[start...end]
       The function assumes that value is postsent in in[] */
    int search(int arr[], int strt, int end, int value)
    {
        int i;
        for (i = strt; i <= end; i++) {
            if (arr[i] == value)
                break;
        }
        return i;
    }
  
    /* This funtcion is here just to test  */
    void preOrder(Node node)
    {
        if (node == null)
            return;
        System.out.print(node.data + " ");
        preOrder(node.left);
        preOrder(node.right);
    }
  
    public static void main(String[] args)
    {
        BinaryTree tree = new BinaryTree();
        int in[] = new int[] { 4, 8, 2, 5, 1, 6, 3, 7 };
        int post[] = new int[] { 8, 4, 5, 2, 6, 7, 3, 1 };
        int n = in.length;
        Node root = tree.buildTree(in, post, n);
        System.out.println("Preorder of the constructed tree : ");
        tree.preOrder(root);
    }
}
  
// This code has been contributed by Mayank Jaiswal(mayank_24)
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to construct tree using 
# inorder and postorder traversals 
  
# Helper function that allocates 
# a new node 
class newNode:
    def __init__(self, data):
        self.data = data 
        self.left = self.right = None
  
# Recursive function to construct binary 
# of size n from Inorder traversal in[] 
# and Postorder traversal post[]. Initial 
# values of inStrt and inEnd should be 
# 0 and n -1. The function doesn't do any 
# error checking for cases where inorder 
# and postorder do not form a tree 
def buildUtil(In, post, inStrt, inEnd, pIndex):
      
    # Base case 
    if (inStrt > inEnd): 
        return None
  
    # Pick current node from Postorder traversal 
    # using postIndex and decrement postIndex 
    node = newNode(post[pIndex[0]]) 
    pIndex[0] -= 1
  
    # If this node has no children 
    # then return 
    if (inStrt == inEnd): 
        return node 
  
    # Else find the index of this node 
    # in Inorder traversal 
    iIndex = search(In, inStrt, inEnd, node.data) 
  
    # Using index in Inorder traversal, 
    # construct left and right subtress 
    node.right = buildUtil(In, post, iIndex + 1
                                  inEnd, pIndex) 
    node.left = buildUtil(In, post, inStrt, 
                        iIndex - 1, pIndex) 
  
    return node
  
# This function mainly initializes index 
# of root and calls buildUtil() 
def buildTree(In, post, n):
    pIndex = [n - 1
    return buildUtil(In, post, 0, n - 1, pIndex)
  
# Function to find index of value in 
# arr[start...end]. The function assumes 
# that value is postsent in in[] 
def search(arr, strt, end, value):
    i = 0
    for i in range(strt, end + 1):
        if (arr[i] == value): 
            break
    return i
  
# This funtcion is here just to test 
def preOrder(node):
    if node == None
        return
    print(node.data,end=" ")
    preOrder(node.left) 
    preOrder(node.right)
  
# Driver code 
if __name__ == '__main__':
    In = [4, 8, 2, 5, 1, 6, 3, 7]
    post = [8, 4, 5, 2, 6, 7, 3, 1
    n = len(In)
  
    root = buildTree(In, post, n) 
  
    print("Preorder of the constructed tree :"
    preOrder(root)
  
# This code is contributed by PranchalK
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to construct a tree using 
// inorder and postorder traversals 
using System;
  
/* A binary tree node has data, pointer 
to left child and a pointer to right child */
public class Node
{
    public int data;
    public Node left, right;
  
    public Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}
  
// Class Index created to implement 
// pass by reference of Index 
public class Index
{
    public int index;
}
  
class GFG
{
/* Recursive function to construct binary 
of size n from Inorder traversal in[] and 
Postrder traversal post[]. Initial values 
of inStrt and inEnd should be 0 and n -1. 
The function doesn't do any error checking 
for cases where inorder and postorder do 
not form a tree */
public virtual Node buildUtil(int[] @in, int[] post, 
                              int inStrt, int inEnd, 
                              Index pIndex)
{
    // Base case 
    if (inStrt > inEnd)
    {
        return null;
    }
  
    /* Pick current node from Postrder traversal 
    using postIndex and decrement postIndex */
    Node node = new Node(post[pIndex.index]);
    (pIndex.index)--;
  
    /* If this node has no children 
    then return */
    if (inStrt == inEnd)
    {
        return node;
    }
  
    /* Else find the index of this node 
    in Inorder traversal */
    int iIndex = search(@in, inStrt, inEnd, node.data);
  
    /* Using index in Inorder traversal, 
    construct left and right subtress */
    node.right = buildUtil(@in, post, iIndex + 1,
                                inEnd, pIndex);
    node.left = buildUtil(@in, post, inStrt,
                               iIndex - 1, pIndex);
  
    return node;
}
  
// This function mainly initializes 
// index of root and calls buildUtil() 
public virtual Node buildTree(int[] @in,
                              int[] post, int n)
{
    Index pIndex = new Index();
    pIndex.index = n - 1;
    return buildUtil(@in, post, 0, n - 1, pIndex);
}
  
/* Function to find index of value in 
arr[start...end]. The function assumes
that value is postsent in in[] */
public virtual int search(int[] arr, int strt, 
                          int end, int value)
{
    int i;
    for (i = strt; i <= end; i++)
    {
        if (arr[i] == value)
        {
            break;
        }
    }
    return i;
}
  
/* This funtcion is here just to test */
public virtual void preOrder(Node node)
{
    if (node == null)
    {
        return;
    }
    Console.Write(node.data + " ");
    preOrder(node.left);
    preOrder(node.right);
}
  
// Driver Code
public static void Main(string[] args)
{
    GFG tree = new GFG();
    int[] @in = new int[] {4, 8, 2, 5, 1, 6, 3, 7};
    int[] post = new int[] {8, 4, 5, 2, 6, 7, 3, 1};
    int n = @in.Length;
    Node root = tree.buildTree(@in, post, n);
    Console.WriteLine("Preorder of the constructed tree : ");
    tree.preOrder(root);
}
}
  
// This code is contributed by Shrikant13
chevron_right

Output
Preorder of the constructed tree : 
1 2 4 8 5 3 6 7 

Time Complexity: O(n2)
Optimized approach: We can optimize the above solution using hashing (unordered_map in C++ or HashMap in Java). We store indexes of inorder traversal in a hash table. So that search can be done O(1) time.
 



filter_none

edit
close

play_arrow

link
brightness_4
code

/* C++ program to construct tree using inorder and 
postorder traversals */
#include <bits/stdc++.h>
  
using namespace std;
  
/* A binary tree node has data, pointer to left 
child and a pointer to right child */
struct Node {
    int data;
    Node *left, *right;
};
  
// Utility function to create a new node
Node* newNode(int data);
  
/* Recursive function to construct binary of size n 
from Inorder traversal in[] and Postorder traversal 
post[]. Initial values of inStrt and inEnd should 
be 0 and n -1. The function doesn't do any error 
checking for cases where inorder and postorder 
do not form a tree */
Node* buildUtil(int in[], int post[], int inStrt,
    int inEnd, int* pIndex, unordered_map<int, int>& mp)
{
    // Base case
    if (inStrt > inEnd)
        return NULL;
  
    /* Pick current node from Postorder traversal  
    using postIndex and decrement postIndex */
    int curr = post[*pIndex];
    Node* node = newNode(curr);
    (*pIndex)--;
  
    /* If this node has no children then return */
    if (inStrt == inEnd)
        return node;
  
    /* Else find the index of this node in Inorder 
    traversal */
    int iIndex = mp[curr];
  
    /* Using index in Inorder traversal, construct 
    left and right subtress */
    node->right = buildUtil(in, post, iIndex + 1,
                            inEnd, pIndex, mp);
    node->left = buildUtil(in, post, inStrt,
                           iIndex - 1, pIndex, mp);
  
    return node;
}
  
// This function mainly creates an unordered_map, then
// calls buildTreeUtil()
struct Node* buildTree(int in[], int post[], int len)
{
    // Store indexes of all items so that we
    // we can quickly find later
    unordered_map<int, int> mp;
    for (int i = 0; i < len; i++)
        mp[in[i]] = i;
  
    int index = len - 1; // Index in postorder
    return buildUtil(in, post, 0, len - 1,
                     &index, mp);
}
  
/* Helper function that allocates a new node */
Node* newNode(int data)
{
    Node* node = (Node*)malloc(sizeof(Node));
    node->data = data;
    node->left = node->right = NULL;
    return (node);
}
  
/* This funtcion is here just to test */
void preOrder(Node* node)
{
    if (node == NULL)
        return;
    printf("%d ", node->data);
    preOrder(node->left);
    preOrder(node->right);
}
  
// Driver code
int main()
{
    int in[] = { 4, 8, 2, 5, 1, 6, 3, 7 };
    int post[] = { 8, 4, 5, 2, 6, 7, 3, 1 };
    int n = sizeof(in) / sizeof(in[0]);
  
    Node* root = buildTree(in, post, n);
  
    cout << "Preorder of the constructed tree : \n";
    preOrder(root);
  
    return 0;
}
chevron_right

Output
Preorder of the constructed tree : 
1 2 4 8 5 3 6 7 

Time Complexity: O(n) 

Another approach

Using stack and set without using recursion.

Below is the implementation of the above idea:

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program for above approach
#include <bits/stdc++.h> 
using namespace std; 
  
/* A binary tree node has data, pointer
to left   child and a pointer to right 
child */
struct Node 
  int data; 
  Node *left, *right; 
  Node(int x)
  {
    data = x;
    left = right = NULL;
  }
};
  
/*Tree building function*/
Node *buildTree(int in[], int post[], int n) 
{
  
  // Create Stack of type Node*
  stack<Node*> st;
  
  // Create Set of type Node*
  set<Node*> s;
  
  // Initialise postIndex with n - 1
  int postIndex = n - 1;
  
  // Initialise root with NULL
  Node* root = NULL;
  
  for (int p = n - 1, i = n - 1; p>=0; )  
  
  
    // Initialise node with NULL
    Node* node = NULL; 
      
    // Run do-while loop
    do
    
  
      // Initialise node with
      // new Node(post[p]); 
      node = new Node(post[p]); 
  
      // Check is root is 
      // equal to NULL
      if (root == NULL) 
      
        root = node; 
      
        
      // If size of set 
      // is greater than 0
      if (st.size() > 0)  
      
          
        // If st.top() is present in the
        // set s
        if (s.find(st.top()) != s.end()) 
        
          s.erase(st.top()); 
          st.top()->left = node; 
          st.pop(); 
        
        else
        
          st.top()->right = node; 
        
      }
        
      st.push(node); 
        
    } while (post[p--] != in[i] && p >=0); 
  
    node = NULL; 
      
    // If the stack is not empty and
    // st.top()->data is equal to in[i]
    while (st.size() > 0 && i>=0 &&  
           st.top()->data == in[i])  
    
      node = st.top(); 
        
      // Pop elements from stack
      st.pop(); 
      i--; 
    
      
    // if node not equal to NULL
    if (node != NULL)  
    
      s.insert(node); 
      st.push(node); 
    
  
    
  // Return root
  return root;
  
}
/* for print preOrder Traversal */
void preOrder(Node* node) 
  if (node == NULL) 
    return
  printf("%d ", node->data); 
  preOrder(node->left); 
  preOrder(node->right); 
}
  
// Driver Code
int main() 
{
  
  int in[] = { 4, 8, 2, 5, 1, 6, 3, 7 }; 
  int post[] = { 8, 4, 5, 2, 6, 7, 3, 1 }; 
  int n = sizeof(in) / sizeof(in[0]); 
  
  // Function Call
  Node* root = buildTree(in, post, n); 
  
  cout << "Preorder of the constructed 
                                tree : \n"; 
  
  // Function Call for preOrder
  preOrder(root); 
  return 0;
}
chevron_right

Output
Preorder of the constructed tree : 
1 2 4 8 5 3 6 7 

This article is contributed by Rishi. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.





Article Tags :
Practice Tags :