Postorder from given Inorder and Preorder (original) (raw)

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

Table of Content

[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.

#include <bits/stdc++.h> using namespace std;

// Find index of a value in inorder traversal int search(vector &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 &in, vector &pre, int inStart, int inEnd, int preStart, vector &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 printPostOrder(vector &in, vector &pre) { vector post;

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

return post;

}

int main() { vector in = {4, 2, 5, 1, 3, 6}; vector 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(' '));

`

[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.

#include <bits/stdc++.h> using namespace std;

// Recursive function to generate postorder traversal void buildPostOrder(vector &in, vector &pre, int inStart, int inEnd, unordered_map<int, int> &mp, int &preIndex, vector &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 printPostOrder(vector &in, vector &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 in = {4, 2, 5, 1, 3, 6}; vector 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(' '));

`