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:
Table of Content
- [Naive Recursive] Searching Root in Inorder - O(n²) Time and O(n) Space
- [Efficient Approach] Hash Map for Inorder Lookup - O(n) Time and O(n) Space
[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 &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.
- 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 &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 postDriver 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(' '));
`
