Postorder from given Inorder and Preorder

Last Updated : 31 May, 2026

Given two arrays represent Inorder and Preorder traversals of a binary tree, the task is to find the Postorder traversal.

Example:

Input: in[] = [4, 2, 5, 1, 3, 6] pre[] = [1, 2, 4, 5, 3, 6]
Output: 4 5 2 6 3 1
Explanation: Traversals in the above example represents following tree:

print-postorder-traversal-from-given-inorder-and-preorder-traversals
Try It Yourself
redirect icon

[Naive Recursive] Searching Root in Inorder - O(n²) Time and O(n) Space

The idea is based on the properties of preorder and inorder traversals. In preorder traversal, the first element is always the root of the current subtree. By searching this root in the inorder traversal, the left and right subtrees can be identified.

  • Take the first element of the current preorder range as the root
  • Find the root's index in the inorder traversal using linear search
  • Recursively process the left and right subtrees
  • Append the root to the postorder traversal
C++
#include <bits/stdc++.h>
using namespace std;

// Find index of a value in inorder traversal
int search(vector<int> &in, int x)
{
    for (int i = 0; i < in.size(); i++)
    {
        if (in[i] == x)
            return i;
    }
    return -1;
}

// Recursive function to generate postorder traversal
void buildPostOrder(vector<int> &in, vector<int> &pre, int inStart, int inEnd, int preStart,
                    vector<int> &post)
{
    // No nodes in this subtree
    if (inStart > inEnd)
        return;

    // First element in preorder is the root
    int root = pre[preStart];

    // Find root position in inorder traversal
    int rootIndex = search(in, root);

    // Process left subtree
    buildPostOrder(in, pre, inStart, rootIndex - 1, preStart + 1, post);

    // Process right subtree
    buildPostOrder(in, pre, rootIndex + 1, inEnd, preStart + (rootIndex - inStart) + 1, post);

    // Add root after left and right subtree
    post.push_back(root);
}

// Function to return postorder traversal
vector<int> printPostOrder(vector<int> &in, vector<int> &pre)
{
    vector<int> post;

    buildPostOrder(in, pre, 0, in.size() - 1, 0, post);

    return post;
}

int main()
{
    vector<int> in = {4, 2, 5, 1, 3, 6};
    vector<int> pre = {1, 2, 4, 5, 3, 6};

    vector<int> post = printPostOrder(in, pre);

    for (int x : post)
        cout << x << " ";

    return 0;
}
Java
// Java program to construct postorder from inorder and preorder traversals
import java.util.*;

class GfG {
    
    // Find index of a value in inorder traversal
    static int search(List<Integer> in, int x) {
        for (int i = 0; i < in.size(); i++) {
            if (in.get(i) == x)
                return i;
        }
        return -1;
    }
    
    // Recursive function to generate postorder traversal
    static void buildPostOrder(List<Integer> in, List<Integer> pre, 
                                int inStart, int inEnd, int preStart,
                                List<Integer> post) {
        // No nodes in this subtree
        if (inStart > inEnd)
            return;
        
        // First element in preorder is the root
        int root = pre.get(preStart);
        
        // Find root position in inorder traversal
        int rootIndex = search(in, root);
        
        // Process left subtree
        buildPostOrder(in, pre, inStart, rootIndex - 1, preStart + 1, post);
        
        // Process right subtree
        buildPostOrder(in, pre, rootIndex + 1, inEnd, 
                      preStart + (rootIndex - inStart) + 1, post);
        
        // Add root after left and right subtree
        post.add(root);
    }
    
    // Function to return postorder traversal
    static List<Integer> printPostOrder(List<Integer> in, List<Integer> pre) {
        List<Integer> post = new ArrayList<>();
        
        buildPostOrder(in, pre, 0, in.size() - 1, 0, post);
        
        return post;
    }
    
    public static void main(String[] args) {
        List<Integer> in = Arrays.asList(4, 2, 5, 1, 3, 6);
        List<Integer> pre = Arrays.asList(1, 2, 4, 5, 3, 6);
        
        List<Integer> post = printPostOrder(in, pre);
        
        for (int x : post) {
            System.out.print(x + " ");
        }
    }
}
Python
# Python program to construct postorder from inorder and preorder traversals

# Find index of a value in inorder traversal
def search(inorder, x):
    for i in range(len(inorder)):
        if inorder[i] == x:
            return i
    return -1

# Recursive function to generate postorder traversal
def buildPostOrder(inorder, preorder, inStart, inEnd, preStart, post):
    # No nodes in this subtree
    if inStart > inEnd:
        return
    
    # First element in preorder is the root
    root = preorder[preStart]
    
    # Find root position in inorder traversal
    rootIndex = search(inorder, root)
    
    # Process left subtree
    buildPostOrder(inorder, preorder, inStart, rootIndex - 1, preStart + 1, post)
    
    # Process right subtree
    leftSize = rootIndex - inStart
    buildPostOrder(inorder, preorder, rootIndex + 1, inEnd, preStart + leftSize + 1, post)
    
    # Add root after left and right subtree
    post.append(root)

# Function to return postorder traversal
def printPostOrder(inorder, preorder):
    post = []
    buildPostOrder(inorder, preorder, 0, len(inorder) - 1, 0, post)
    return post

# Driver code
if __name__ == "__main__":
    inorder = [4, 2, 5, 1, 3, 6]
    preorder = [1, 2, 4, 5, 3, 6]
    
    post = printPostOrder(inorder, preorder)
    
    print(' '.join(map(str, post)))
C#
// C# program to construct postorder from inorder and preorder traversals
using System;
using System.Collections.Generic;

class GfG {
    
    // Find index of a value in inorder traversal
    static int search(List<int> inList, int x) {
        for (int i = 0; i < inList.Count; i++) {
            if (inList[i] == x)
                return i;
        }
        return -1;
    }
    
    // Recursive function to generate postorder traversal
    static void buildPostOrder(List<int> inList, List<int> pre, 
                                int inStart, int inEnd, int preStart,
                                List<int> post) {
        // No nodes in this subtree
        if (inStart > inEnd)
            return;
        
        // First element in preorder is the root
        int root = pre[preStart];
        
        // Find root position in inorder traversal
        int rootIndex = search(inList, root);
        
        // Process left subtree
        buildPostOrder(inList, pre, inStart, rootIndex - 1, preStart + 1, post);
        
        // Process right subtree
        int leftSize = rootIndex - inStart;
        buildPostOrder(inList, pre, rootIndex + 1, inEnd, preStart + leftSize + 1, post);
        
        // Add root after left and right subtree
        post.Add(root);
    }
    
    // Function to return postorder traversal
    static List<int> printPostOrder(List<int> inList, List<int> pre) {
        List<int> post = new List<int>();
        
        buildPostOrder(inList, pre, 0, inList.Count - 1, 0, post);
        
        return post;
    }
    
    static void Main(string[] args) {
        List<int> inorder = new List<int> { 4, 2, 5, 1, 3, 6 };
        List<int> preorder = new List<int> { 1, 2, 4, 5, 3, 6 };
        
        List<int> post = printPostOrder(inorder, preorder);
        
        foreach (int x in post) {
            Console.Write(x + " ");
        }
    }
}
JavaScript
// JavaScript program to construct postorder from inorder and preorder traversals

// Find index of a value in inorder traversal
function search(inorder, x) {
    for (let i = 0; i < inorder.length; i++) {
        if (inorder[i] === x)
            return i;
    }
    return -1;
}

// Recursive function to generate postorder traversal
function buildPostOrder(inorder, preorder, inStart, inEnd, preStart, post) {
    // No nodes in this subtree
    if (inStart > inEnd)
        return;
    
    // First element in preorder is the root
    let root = preorder[preStart];
    
    // Find root position in inorder traversal
    let rootIndex = search(inorder, root);
    
    // Process left subtree
    buildPostOrder(inorder, preorder, inStart, rootIndex - 1, preStart + 1, post);
    
    // Process right subtree
    let leftSize = rootIndex - inStart;
    buildPostOrder(inorder, preorder, rootIndex + 1, inEnd, preStart + leftSize + 1, post);
    
    // Add root after left and right subtree
    post.push(root);
}

// Function to return postorder traversal
function printPostOrder(inorder, preorder) {
    let post = [];
    buildPostOrder(inorder, preorder, 0, inorder.length - 1, 0, post);
    return post;
}

// Driver code
const inorder = [4, 2, 5, 1, 3, 6];
const preorder = [1, 2, 4, 5, 3, 6];

const post = printPostOrder(inorder, preorder);

console.log(post.join(' '));

Output
4 5 2 6 3 1 

[Efficient Approach] Hash Map for Inorder Lookup - O(n) Time and O(n) Space

The idea is to avoid repeatedly searching for the root in the inorder traversal. A hash map is used to store the index of every node in the inorder traversal.

  • Store each inorder value and its index in a hash map
  • Maintain a preorder index pointing to the current root
  • For each recursive call: Take the current preorder element as the root and find its inorder position using the hash map
  • Recursively process the left and right subtrees
  • Add the root to the postorder traversal
  • Return the generated postorder traversal
C++
#include <bits/stdc++.h>
using namespace std;

// Recursive function to generate postorder traversal
void buildPostOrder(vector<int> &in, vector<int> &pre, int inStart, int inEnd, unordered_map<int, int> &mp,
                    int &preIndex, vector<int> &post)
{
    // No nodes in this subtree
    if (inStart > inEnd)
        return;

    // Current root from preorder traversal
    int root = pre[preIndex++];

    // Find root position in inorder traversal
    int inIndex = mp[root];

    // Build left subtree
    buildPostOrder(in, pre, inStart, inIndex - 1, mp, preIndex, post);

    // Build right subtree
    buildPostOrder(in, pre, inIndex + 1, inEnd, mp, preIndex, post);

    // Add root after left and right subtree
    post.push_back(root);
}

// Function to return postorder traversal
vector<int> printPostOrder(vector<int> &in, vector<int> &pre)
{
    int n = in.size();

    // Stores value -> index mapping for inorder traversal
    unordered_map<int, int> mp;

    for (int i = 0; i < n; i++)
        mp[in[i]] = i;

    vector<int> post;
    int preIndex = 0;

    buildPostOrder(in, pre, 0, n - 1, mp, preIndex, post);

    return post;
}

int main()
{
    vector<int> in = {4, 2, 5, 1, 3, 6};
    vector<int> pre = {1, 2, 4, 5, 3, 6};

    vector<int> post = printPostOrder(in, pre);

    for (int x : post)
        cout << x << " ";

    return 0;
}
Java
// Java program to construct postorder from inorder and preorder traversals
import java.util.*;

class GfG {
    
    // Recursive function to generate postorder traversal
    static void buildPostOrder(List<Integer> in, List<Integer> pre,
                                int inStart, int inEnd,
                                Map<Integer, Integer> mp,
                                int[] preIndex,
                                List<Integer> post) {
        // No nodes in this subtree
        if (inStart > inEnd)
            return;
        
        // Current root from preorder traversal
        int root = pre.get(preIndex[0]);
        preIndex[0]++;
        
        // Find root position in inorder traversal
        int inIndex = mp.get(root);
        
        // Build left subtree
        buildPostOrder(in, pre, inStart, inIndex - 1,
                       mp, preIndex, post);
        
        // Build right subtree
        buildPostOrder(in, pre, inIndex + 1, inEnd,
                       mp, preIndex, post);
        
        // Add root after left and right subtree
        post.add(root);
    }
    
    // Function to return postorder traversal
    static List<Integer> printPostOrder(List<Integer> in, List<Integer> pre) {
        int n = in.size();
        
        // Stores value -> index mapping for inorder traversal
        Map<Integer, Integer> mp = new HashMap<>();
        
        for (int i = 0; i < n; i++)
            mp.put(in.get(i), i);
        
        List<Integer> post = new ArrayList<>();
        int[] preIndex = {0};
        
        buildPostOrder(in, pre, 0, n - 1,
                       mp, preIndex, post);
        
        return post;
    }
    
    public static void main(String[] args) {
        List<Integer> in = Arrays.asList(4, 2, 5, 1, 3, 6);
        List<Integer> pre = Arrays.asList(1, 2, 4, 5, 3, 6);
        
        List<Integer> post = printPostOrder(in, pre);
        
        for (int x : post) {
            System.out.print(x + " ");
        }
    }
}
Python
# Python program to construct postorder from inorder and preorder traversals

# Recursive function to generate postorder traversal
def buildPostOrder(inorder, preorder, inStart, inEnd, mp, preIndex, post):
    # No nodes in this subtree
    if inStart > inEnd:
        return
    
    # Current root from preorder traversal
    root = preorder[preIndex[0]]
    preIndex[0] += 1
    
    # Find root position in inorder traversal
    inIndex = mp[root]
    
    # Build left subtree
    buildPostOrder(inorder, preorder, inStart, inIndex - 1,
                   mp, preIndex, post)
    
    # Build right subtree
    buildPostOrder(inorder, preorder, inIndex + 1, inEnd,
                   mp, preIndex, post)
    
    # Add root after left and right subtree
    post.append(root)

# Function to return postorder traversal
def printPostOrder(inorder, preorder):
    n = len(inorder)
    
    # Stores value -> index mapping for inorder traversal
    mp = {}
    
    for i in range(n):
        mp[inorder[i]] = i
    
    post = []
    preIndex = [0]
    
    buildPostOrder(inorder, preorder, 0, n - 1,
                   mp, preIndex, post)
    
    return post

# Driver code
if __name__ == "__main__":
    inorder = [4, 2, 5, 1, 3, 6]
    preorder = [1, 2, 4, 5, 3, 6]
    
    post = printPostOrder(inorder, preorder)
    
    print(' '.join(map(str, post)))
C#
// C# program to construct postorder from inorder and preorder traversals
using System;
using System.Collections.Generic;

class GfG {
    
    // Recursive function to generate postorder traversal
    static void buildPostOrder(List<int> inList, List<int> pre,
                                int inStart, int inEnd,
                                Dictionary<int, int> mp,
                                ref int preIndex,
                                List<int> post) {
        // No nodes in this subtree
        if (inStart > inEnd)
            return;
        
        // Current root from preorder traversal
        int root = pre[preIndex];
        preIndex++;
        
        // Find root position in inorder traversal
        int inIndex = mp[root];
        
        // Build left subtree
        buildPostOrder(inList, pre, inStart, inIndex - 1,
                       mp, ref preIndex, post);
        
        // Build right subtree
        buildPostOrder(inList, pre, inIndex + 1, inEnd,
                       mp, ref preIndex, post);
        
        // Add root after left and right subtree
        post.Add(root);
    }
    
    // Function to return postorder traversal
    static List<int> printPostOrder(List<int> inList, List<int> pre) {
        int n = inList.Count;
        
        // Stores value -> index mapping for inorder traversal
        Dictionary<int, int> mp = new Dictionary<int, int>();
        
        for (int i = 0; i < n; i++)
            mp[inList[i]] = i;
        
        List<int> post = new List<int>();
        int preIndex = 0;
        
        buildPostOrder(inList, pre, 0, n - 1,
                       mp, ref preIndex, post);
        
        return post;
    }
    
    static void Main(string[] args) {
        List<int> inorder = new List<int> { 4, 2, 5, 1, 3, 6 };
        List<int> preorder = new List<int> { 1, 2, 4, 5, 3, 6 };
        
        List<int> post = printPostOrder(inorder, preorder);
        
        foreach (int x in post) {
            Console.Write(x + " ");
        }
    }
}
JavaScript
// JavaScript program to construct postorder from inorder and preorder traversals

// Recursive function to generate postorder traversal
function buildPostOrder(inorder, preorder, inStart, inEnd, mp, preIndex, post) {
    // No nodes in this subtree
    if (inStart > inEnd)
        return;
    
    // Current root from preorder traversal
    let root = preorder[preIndex[0]];
    preIndex[0]++;
    
    // Find root position in inorder traversal
    let inIndex = mp.get(root);
    
    // Build left subtree
    buildPostOrder(inorder, preorder, inStart, inIndex - 1,
                   mp, preIndex, post);
    
    // Build right subtree
    buildPostOrder(inorder, preorder, inIndex + 1, inEnd,
                   mp, preIndex, post);
    
    // Add root after left and right subtree
    post.push(root);
}

// Function to return postorder traversal
function printPostOrder(inorder, preorder) {
    const n = inorder.length;
    
    // Stores value -> index mapping for inorder traversal
    let mp = new Map();
    
    for (let i = 0; i < n; i++)
        mp.set(inorder[i], i);
    
    let post = [];
    let preIndex = [0];
    
    buildPostOrder(inorder, preorder, 0, n - 1,
                   mp, preIndex, post);
    
    return post;
}

// Driver code
const inorder = [4, 2, 5, 1, 3, 6];
const preorder = [1, 2, 4, 5, 3, 6];

const post = printPostOrder(inorder, preorder);

console.log(post.join(' '));

Output
4 5 2 6 3 1 
Comment