Binary Tree From Preorder and Postorder traversal

Last Updated : 8 Oct, 2025

Given postorder and preorder traversals of a Binary Tree in array post[] and pre[] respectively, Construct the Binary Tree and return it’s root.

Note: All values in post[] and pre[] are distinct.

Examples:

Input: pre[] = [1, 2, 4, 8, 9, 5, 3, 6, 7], post[] = [8, 9, 4, 5, 2, 6, 7, 3, 1]
Output: [[1], [2, 3], [4, 5, 6, 7], [8, 9, N, N, N, N, N, N]]
Explanation: The tree looks like:

420046665


Input: pre[] = [1, 2, 4, 5, 3, 6, 7], post[] = [4, 5, 2, 6, 7, 3, 1]
Output: [[1], [2, 3], [4, 5, 6, 7]]
Explanation: The tree looks like:

11
Try It Yourself
redirect icon

[Approach] Recursive Binary Tree Reconstruction - O(n2) Time and O(n) Space

The main idea is that a general binary tree cannot always be uniquely constructed from preorder and postorder traversals alone, because multiple trees may produce the same pair of traversals. Still, we can reconstruct one valid tree by using the relationship between the traversal orders.

  • The first element in preorder is always the root of the current subtree.
  • The next element in preorder represents the left child, whose position in postorder helps determine the extent of the left subtree.
  • All nodes in postorder up to that position form the left subtree, and the remaining nodes (excluding the root) form the right subtree.
  • We then recursively construct the left and right subtrees using their respective preorder and postorder segments and attach them to the root.
C++
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

// Node Structure
class Node {
public:
    int data;
    Node *left;
    Node *right;
    Node(int x) {
        data = x;
        left = right = nullptr;
    }
};

// Recursive function to construct binary
// tree from preorder and postorder
Node* constructTreeUtil(vector<int> &pre, vector<int> &post, int &preIndex,
                        int l, int h, int size) {
    if (preIndex >= size || l > h)
        return nullptr;

    // Create root node from current preorder element
    Node* root = new Node(pre[preIndex++]);

    // If there is only one element, return it as leaf node
    if (l == h)
        return root;

    // Find the next preorder element in postorder
    // to split left and right subtrees
    int i;
    for (i = l; i <= h; ++i)
        if (pre[preIndex] == post[i])
            break;

    if (i <= h) {
        
        // Recursively construct left and right subtrees
        root->left = constructTreeUtil(pre, post, preIndex, l, i, size);
        root->right = constructTreeUtil(pre, post, preIndex, i + 1, h - 1, size);
    }

    return root;
}

// Function to construct Binary Tree from preorder and postorder
Node* constructTree(vector<int> &pre, vector<int> &post) {
    int preIndex = 0;
    return constructTreeUtil(pre, post, preIndex, 0, pre.size() - 1, pre.size());
}

int getHeight(Node* root, int h) {
    if (root == nullptr) return h - 1;
    return max(getHeight(root->left, h + 1), getHeight(root->right, h + 1));
}

void levelOrder(Node* root) {
    queue<pair<Node*, int>> q;
    q.push({root, 0});

    int lastLevel = 0;

    // function to get the height of tree
    int height = getHeight(root, 0);

    // printing the level order of tree
    while (!q.empty()) {
        auto top = q.front(); q.pop();
        Node* node = top.first;
        int lvl = top.second;

        if (lvl > lastLevel) {
            cout << "\n";
            lastLevel = lvl;
        }

        // all levels are printed
        if (lvl > height) break;

        
        if (node->data != -1) cout << node->data << " ";
        
        // printing null node
        else cout << "N ";

        // null node has no children
        if (node->data == -1) continue;

        if (node->left == nullptr) q.push({new Node(-1), lvl + 1});
        else q.push({node->left, lvl + 1});

        if (node->right == nullptr) q.push({new Node(-1), lvl + 1});
        else q.push({node->right, lvl + 1});
    }
}

int main () {
  
    vector<int> pre = {1, 2, 4, 8, 9, 5, 3, 6, 7};
    vector<int> post = {8, 9, 4, 5, 2, 6, 7, 3, 1};

    Node *root = constructTree(pre, post);

    levelOrder(root);

    return 0;
}
Java
import java.util.LinkedList;
import java.util.Queue;
import java.util.List;
import java.util.ArrayList;

// Node Structure
class Node {
    int data;
    Node left, right;

    Node(int x)
    {
        data = x;
        left = right = null;
    }
}

class GFG {

     // Recursive function to construct
     // binary tree from preorder and postorder
    static Node constructTreeUtil(int[] pre, int[] post, int[] preIndex, 
                                                    int l, int h, int size) {
        if (preIndex[0] >= size || l > h)
            return null;
    
        // Create root node from current preorder element
        Node root = new Node(pre[preIndex[0]++]);
    
        // If there is only one element, return it as leaf node
        if (l == h)
            return root;
    
        // Find the next preorder element in postorder to 
        // split left and right subtrees
        int i;
        for (i = l; i <= h; i++)
            if (pre[preIndex[0]] == post[i])
                break;
    
        if (i <= h) {
           
            // Recursively construct left and right subtrees
            root.left = constructTreeUtil(pre, post, preIndex, l, i, size);
            root.right = constructTreeUtil(pre, post, preIndex, i + 1, h - 1, size);
        }
    
        return root;
    }
    
    // Main function to construct binary tree
    static Node constructTree(int[] pre, int[] post) {
        int[] preIndex = { 0 };
        int size = pre.length;
        return constructTreeUtil(pre, post, preIndex, 0, size - 1, size);
    }

    static int getHeight( Node root, int h ) {
        if( root == null ) return h-1;
        
        return Math.max(getHeight(root.left, h+1), getHeight(root.right, h+1));
    }
    
    static void levelOrder(Node root) {
        Queue<List<Object>> queue = new LinkedList<>();
        queue.offer(List.of(root, 0));
        
        int lastLevel = 0;
        
        // function to get the height of tree
        int height = getHeight(root, 0);
        
        // printing the level order of tree
        while( !queue.isEmpty()) {
            List<Object> top = queue.poll();
            
            Node node = (Node) top.get(0);
            int lvl = (int) top.get(1);
            
            if( lvl > lastLevel ) {
                System.out.println();
                lastLevel = lvl;
            }
            
            // all levels are printed
            if( lvl > height ) break;
            
            // printing null node
            System.out.print((node.data == -1 ? "N" : node.data) + " ");
            
            // null node has no children
            if( node.data == -1 ) continue;
            
            if( node.left == null ) queue.offer(List.of(new Node(-1), lvl+1));
            else queue.offer(List.of(node.left, lvl+1));
            
            if( node.right == null ) queue.offer(List.of(new Node(-1), lvl+1));
            else queue.offer(List.of(node.right, lvl+1));
        }
    }

    public static void main(String[] args) {
        int[] pre = {1, 2, 4, 8, 9, 5, 3, 6, 7};
        int[] post = {8, 9, 4, 5, 2, 6, 7, 3, 1};

        Node root = constructTree(pre, post);

        levelOrder(root);
    }
}
Python
from collections import deque

# Node Structure
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None

# Recursive function to construct
# binary tree from preorder and postorder
def constructTreeUtil(pre, post, preIndex, l, h, size):
    if preIndex[0] >= size or l > h:
        return None

    # Create root node from current preorder element
    root = Node(pre[preIndex[0]])
    preIndex[0] += 1

    # If there is only one element, return it as leaf node
    if l == h:
        return root

    # Find the next preorder element in 
    # postorder to split left and right subtrees
    i = l
    while i <= h and pre[preIndex[0]] != post[i]:
        i += 1

    if i <= h:
        # Recursively construct left and right subtrees
        root.left = constructTreeUtil(pre, post, preIndex, l, i, size)
        root.right = constructTreeUtil(pre, post, preIndex, i + 1, h - 1, size)

    return root

# Main function to construct binary tree
def constructTree(pre, post):
    preIndex = [0]
    size = len(pre)
    return constructTreeUtil(pre, post, preIndex, 0, size - 1, size)
    
def getHeight(root, h):
    if root is None:
        return h - 1
    return max(getHeight(root.left, h + 1), getHeight(root.right, h + 1))


def levelOrder(root):
    queue = deque([[root, 0]])
    lastLevel = 0

    # function to get the height of tree
    height = getHeight(root, 0)

    # printing the level order of tree
    while queue:
        node, lvl = queue.popleft()

        if lvl > lastLevel:
            print()
            lastLevel = lvl

        # all levels are printed
        if lvl > height:
            break

        # printing null node
        print("N" if node.data == -1 else node.data, end=" ")

        # null node has no children
        if node.data == -1:
            continue

        if node.left is None:
            queue.append([Node(-1), lvl + 1])
        else:
            queue.append([node.left, lvl + 1])

        if node.right is None:
            queue.append([Node(-1), lvl + 1])
        else:
            queue.append([node.right, lvl + 1])
            
if __name__ == "__main__":

    pre = [1, 2, 4, 8, 9, 5, 3, 6, 7]
    post = [8, 9, 4, 5, 2, 6, 7, 3, 1]

    root = constructTree(pre, post)

    levelOrder(root)
C#
using System;
using System.Collections.Generic;

// Node Structure
class Node {
    public int data;
    public Node left, right;

    public Node(int x) {
        data = x;
        left = right = null;
    }
}

class GFG {
    
    // Recursive function to construct binary tree
    // from preorder and postorder
    static Node constructTreeUtil(int[] pre, int[] post, ref int preIndex,
                                                            int l, int h, int size) {
        if (preIndex >= size || l > h)
            return null;

        // Create root node from current preorder element
        Node root = new Node(pre[preIndex++]);

        // If there is only one element, return it as leaf node
        if (l == h)
            return root;

        // Find the next preorder element in postorder
        // to split left and right subtrees
        int i = l;
        while (i <= h && pre[preIndex] != post[i])
            i++;

        if (i <= h) {
           
            // Recursively construct left and right subtrees
            root.left = constructTreeUtil(pre, post, ref preIndex, l, i, size);
            root.right = constructTreeUtil(pre, post, ref preIndex, i + 1, h - 1, size);
        }

        return root;
    }

    // Main function to construct full binary tree
    static Node constructTree(int[] pre, int[] post) {
        int preIndex = 0;
        int size = pre.Length;
        return constructTreeUtil(pre, post, ref preIndex, 0, size - 1, size);
    }

    static int getHeight(Node root, int h) {
        if (root == null) return h - 1;
        return Math.Max(getHeight(root.left, h + 1), getHeight(root.right, h + 1));
    }

    static void levelOrder(Node root) {
        Queue<(Node, int)> queue = new Queue<(Node, int)>();
        queue.Enqueue((root, 0));

        int lastLevel = 0;

        // function to get the height of tree
        int height = getHeight(root, 0);

        // printing the level order of tree
        while (queue.Count > 0) {
            var (node, lvl) = queue.Dequeue();

            if (lvl > lastLevel) {
                Console.WriteLine();
                lastLevel = lvl;
            }

            // all levels are printed
            if (lvl > height) break;

            // printing null node
            Console.Write((node.data == -1 ? "N" : node.data.ToString()) + " ");

            // null node has no children
            if (node.data == -1) continue;

            if (node.left == null) queue.Enqueue((new Node(-1), lvl + 1));
            else queue.Enqueue((node.left, lvl + 1));

            if (node.right == null) queue.Enqueue((new Node(-1), lvl + 1));
            else queue.Enqueue((node.right, lvl + 1));
        }
    }

    public static void Main() {
        int[] pre = {1, 2, 4, 8, 9, 5, 3, 6, 7};
        int[] post = {8, 9, 4, 5, 2, 6, 7, 3, 1};

        Node root = constructTree(pre, post);
        levelOrder(root);
    }
}
JavaScript
// Queue node
class QNode {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

// Node Structure
class Node {
    constructor(data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

class Queue {
    constructor() {
        this.front = null;
        this.rear = null;
    }

    isEmpty() {
        return this.front === null;
    }

    enqueue(x) {
        let newNode = new QNode(x);
        if (this.rear === null) {
            this.front = this.rear = newNode;
            return;
        }
        this.rear.next = newNode;
        this.rear = newNode;
    }

    dequeue() {
        if (this.front === null)
            return null;

        let temp = this.front;
        this.front = this.front.next;

        if (this.front === null)
            this.rear = null;

        return temp.data;
    }
}

// Recursive function to construct 
// binary tree from preorder and postorder
function constructTreeUtil(pre, post, preIndex, l, h, size) {
    if (preIndex.index >= size || l > h) return null;

    // Create root node from current preorder element
    let root = new Node(pre[preIndex.index++]);

    // If there is only one element, return it as leaf node
    if (l === h) return root;

    // Find the next preorder element in
    // postorder to split left and right subtrees
    let i = l;
    while (i <= h && pre[preIndex.index] !== post[i]) i++;

    if (i <= h) {
       
        // Recursively construct left and right subtrees
        root.left = constructTreeUtil(pre, post, preIndex, l, i, size);
        root.right = constructTreeUtil(pre, post, preIndex, i + 1, h - 1, size);
    }

    return root;
}

// Main function to construct full binary tree
function constructTree(pre, post) {
    
    // Using object for pass-by-reference
    let preIndex = { index: 0 }; 
    let size = pre.length;
    return constructTreeUtil(pre, post, preIndex, 0, size - 1, size);
}

function getHeight(root, h) {
    if (root === null) return h - 1;
    return Math.max(getHeight(root.left, h + 1), getHeight(root.right, h + 1));
}

function levelOrder(root) {
    let queue = [];
    queue.push([root, 0]);

    let lastLevel = 0;

    // get the height of tree
    let height = getHeight(root, 0);

    // printing the level order of tree
    while (queue.length > 0) {
        let [node, lvl] = queue.shift();

        if (lvl > lastLevel) {
            console.log("");
            lastLevel = lvl;
        }

        // all levels are printed
        if (lvl > height) break;

        // printing null node
        process.stdout.write((node.data === -1 ? "N" : node.data) + " ");

        // null node has no children
        if (node.data === -1) continue;

        if (node.left === null) queue.push([new Node(-1), lvl + 1]);
        else queue.push([node.left, lvl + 1]);

        if (node.right === null) queue.push([new Node(-1), lvl + 1]);
        else queue.push([node.right, lvl + 1]);
    }
}

//Driver Code
const pre = [ 1, 2, 4, 8, 9, 5, 3, 6, 7 ];
const post = [ 8, 9, 4, 5, 2, 6, 7, 3, 1 ];

const root = constructTree(pre, post);
levelOrder(root);

Output
1 
2 3 
4 5 6 7 
8 9 N N N N N N 

[Expected Approach] Using HashMap and Recursion - O(n) Time and O(n) Space

The idea is to use the properties of preorder (NLR) and postorder (LRN) traversals. In preorder, the first element is always the root, which serves as the starting point for constructing the tree. The next element in preorder belongs to the left subtree, and its position in the postorder array helps to divide the tree into two parts: the elements before this position form the left subtree, and the elements after it form the right subtree. To find this position efficiently, we use a HashMap for constant-time lookup, and then recursively split the array to build the left and right subtrees and rebuild the entire tree.

C++
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
using namespace std;

// Node Structure
class Node
{
  public:
    int data;
    Node *left;
    Node *right;
    Node(int x)
    {
        data = x;
        left = right = nullptr;
    }
};

// Recursive function to construct binary
// tree from preorder and postorder
Node *constructTreeUtil(vector<int> &pre, vector<int> &post, int &preIndex,

                    int l, int h, int size, unordered_map<int, int> &postMap)
                        
{
    if (preIndex >= size || l > h)
        return nullptr;
    Node *root = new Node(pre[preIndex++]);

    // If there is only one element,
    // return it as leaf node
    if (l == h)
        return root;

    // Find the next preorder element
    // in postorder using hashmap
    int i = postMap[pre[preIndex]];

    if (i <= h)
    {
        root->left = constructTreeUtil(pre, post, preIndex, 
        
                                       l, i, size, postMap);

        root->right = constructTreeUtil(pre, post, preIndex, i + 1,
                                            h - 1, size, postMap);
    }

    return root;
}

// Function to construct Binary Tree
// from preorder and postorder
Node *constructTree(vector<int> &pre, vector<int> &post)
{
    int preIndex = 0;
    int size = pre.size();

    // Build hashmap for postorder element
    unordered_map<int, int> postMap;
    for (int i = 0; i < size; i++)
        postMap[post[i]] = i;

    return constructTreeUtil(pre, post, preIndex,
                                0, size - 1, size, postMap);
}

// Function to get the height of the tree
int getHeight(Node *root, int h)
{
    if (root == nullptr)
        return h - 1;
    return max(getHeight(root->left, h + 1), 
                   getHeight(root->right, h + 1));
}

// Level Order traversal
void levelOrder(Node *root)
{
    queue<pair<Node *, int>> q;
    q.push({root, 0});

    int lastLevel = 0;
    int height = getHeight(root, 0);

    while (!q.empty())
    {
        auto top = q.front();
        q.pop();
        Node *node = top.first;
        int lvl = top.second;

        if (lvl > lastLevel)
        {
            cout << "\n";
            lastLevel = lvl;
        }

        // all levels are printed
        if (lvl > height)
            break;

        // print null node as "N"
        if (node->data != -1)
            cout << node->data << " ";
        else
            cout << "N ";

        // null nodes have no children
        if (node->data == -1)
            continue;

        if (node->left == nullptr)
            q.push({new Node(-1), lvl + 1});
        else
            q.push({node->left, lvl + 1});

        if (node->right == nullptr)
            q.push({new Node(-1), lvl + 1});
        else
            q.push({node->right, lvl + 1});
    }
}

int main()
{
    vector<int> pre = {1, 2, 4, 8, 9, 5, 3, 6, 7};
    vector<int> post = {8, 9, 4, 5, 2, 6, 7, 3, 1};

    Node *root = constructTree(pre, post);
    levelOrder(root);

    return 0;
}
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;

// Node structure
class Node {
    int data;
    Node left, right;
    Node(int x) {
        data = x;
        left = right = null;
    }
}

public class ConstructTree {

    // Recursive function to construct binary
    // tree from preorder and postorder
    static Node constructTreeUtil(int[] pre, int[] post, int[] preIndex,int l, int h, 
                                         int size, HashMap<Integer,Integer> postMap) {
        if (preIndex[0] >= size || l > h) 
        return null;

        Node root = new Node(pre[preIndex[0]++]);

        // If there is only one element, 
        // return it as leaf node
        if (l == h) return root;

        // Find the next preorder element in 
        // postorder using hashmap
        int i = postMap.get(pre[preIndex[0]]);

        if (i <= h) {
            // Recursively construct left and right subtrees
            root.left = constructTreeUtil(pre, post, preIndex, l,
                                                  i, size, postMap);
            root.right = constructTreeUtil(pre, post, preIndex, i + 1,
                                                   h - 1, size, postMap);
        }

        return root;
    }

    // Function to construct Binary Tree
    // from preorder and postorder
    static Node constructTree(int[] pre, int[] post) {
        int size = pre.length;
        int[] preIndex = {0};
    
     // Build hashmap for postorder element 
        HashMap<Integer,Integer> postMap = new HashMap<>();
        for (int i = 0; i < size; i++) 
              postMap.put(post[i], i);

        return constructTreeUtil(pre, post, preIndex, 0, 
                                size - 1, size, postMap);
    }

    // Function to get the height of tree
    static int getHeight(Node root, int h) {
        if (root == null) return h - 1;
        return Math.max(getHeight(root.left, h + 1), 
                           getHeight(root.right, h + 1));
    }

    // Level Order traversal
    static void levelOrder(Node root) {
        Queue<Node> q = new LinkedList<>();
        q.add(root);
        int lastLevel = 0;
        int height = getHeight(root, 0);

        class Pair {
            Node node; int level;
            Pair(Node n, int l){ node = n; level = l;}
        }

        Queue<Pair> pq = new LinkedList<>();
        pq.add(new Pair(root, 0));

        while (!pq.isEmpty()) {
            Pair top = pq.poll();
            Node node = top.node;
            int lvl = top.level;

            if (lvl > lastLevel) {
                System.out.println();
                lastLevel = lvl;
            }
            
             // all levels are printed
            if (lvl > height) break;

             // print null node as "N"
            if (node.data != -1) 
            System.out.print(node.data + " ");
            else System.out.print("N ");
 
            //  Null nodes have no children
            if (node.data == -1) continue;

            if (node.left == null) 
            pq.add(new Pair(new Node(-1), lvl + 1));
            else
            pq.add(new Pair(node.left, lvl + 1));

            if (node.right == null) 
            pq.add(new Pair(new Node(-1), lvl + 1));
            else 
            pq.add(new Pair(node.right, lvl + 1));
        }
    }

    public static void main(String[] args) {
        int[] pre = {1, 2, 4, 8, 9, 5, 3, 6, 7};
        int[] post = {8, 9, 4, 5, 2, 6, 7, 3, 1};

        Node root = constructTree(pre, post);
        levelOrder(root);
    }
}
Python
# Node structure
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

# Recursive function to construct binary tree from preorder and postorder
def constructTreeUtil(pre, post, preIndex, l, h, postMap):
    if preIndex[0] >= len(pre) or l > h:
        return None

    root = Node(pre[preIndex[0]])
    preIndex[0] += 1

    # If there is only one element,
    # return it as leaf node
    if l == h:
        return root

    # Find the next preorder element
    # in postorder using hashmap
    i = postMap[pre[preIndex[0]]]
    if i <= h:
        root.left = constructTreeUtil(pre, post, preIndex,
                                            l, i, postMap)
        root.right = constructTreeUtil(pre, post, preIndex, 
                                          i + 1, h - 1, postMap)

    return root

# Function to construct Binary Tree
# from preorder and postorder
def constructTree(pre, post):
    
    # Build hashmap for postorder element 
    postMap = {val: idx for idx, val in enumerate(post)}
    preIndex = [0] 
    return constructTreeUtil(pre, post, preIndex, 
                                     0, len(pre) - 1, postMap)

# Function to get the height of the tree
def getHeight(root, h):
    if root is None:
        return h - 1
    return max(getHeight(root.left, h + 1),
                            getHeight(root.right, h + 1))

# Level Order traversal with printing null nodes as "N"
from collections import deque
def levelOrder(root):
    q = deque()
    q.append((root, 0))  
    lastLevel = 0
    height = getHeight(root, 0)

    while q:
        node, lvl = q.popleft()
        if lvl > lastLevel:
            print()
            lastLevel = lvl
            
        #  all levels are printed
        if (lvl > height):
            break

        #  print null node as "N"
        print(node.data if node.data != -1 else "N", end=" ")

        # Null nodes do not have children
        if node.data == -1:
            continue

        q.append((node.left if node.left else Node(-1), lvl + 1))
        q.append((node.right if node.right else Node(-1), lvl + 1))
    print()

if __name__== "__main__":
    pre = [1, 2, 4, 8, 9, 5, 3, 6, 7]
    post = [8, 9, 4, 5, 2, 6, 7, 3, 1]
    root = constructTree(pre, post)
    levelOrder(root)
C#
using System;
using System.Collections.Generic;

// Node Structure
class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int x) {
        data = x;
        left = right = null;
    }
}

class GFG {

    // Recursive function to construct binary
    // tree from preorder and postorder
    static Node constructTreeUtil(int[] pre, int[] post, ref int preIndex,int l,
                                     int h, int size, Dictionary<int, int> postMap) {
                                         
        if (preIndex >= size || l > h)
            return null;

        Node root = new Node(pre[preIndex++]);

        // If there is only one element,
        // return it as leaf node
        if (l == h)
            return root;

        // Find the next preorder element
        // in postorder using hashmap
        int i = postMap[pre[preIndex]];

        if (i <= h) {
          root.left = constructTreeUtil(pre, post, ref preIndex,
                                                l, i, size, postMap);
                                                
          root.right = constructTreeUtil(pre, post, ref preIndex,
                                                 i + 1, h - 1, size, postMap);
        }

        return root;
    }

    // Function to construct Binary Tree 
    // from preorder and postorder
    static Node constructTree(int[] pre, int[] post) {
        int preIndex = 0;
        int size = pre.Length;

        // Build hashmap for postorder element 
        Dictionary<int, int> postMap = new Dictionary<int, int>();
        for (int i = 0; i < size; i++)
            postMap[post[i]] = i;

        return constructTreeUtil(pre, post, ref preIndex, 
                                         0, size - 1, size, postMap);
    }

    // Function to get the height of the tree
    static int getHeight(Node root, int h) {
        if (root == null) return h - 1;
        return Math.Max(getHeight(root.left, h + 1), 
                                getHeight(root.right, h + 1));
    }

    // Level Order traversal
    static void levelOrder(Node root) {
        Queue<(Node, int)> q = new Queue<(Node, int)>();
        q.Enqueue((root, 0));

        int lastLevel = 0;
        int height = getHeight(root, 0);

        while (q.Count > 0) {
            var top = q.Dequeue();
            Node node = top.Item1;
            int lvl = top.Item2;

            if (lvl > lastLevel) {
                Console.WriteLine();
                lastLevel = lvl;
            }
            
             // all levels are printed
            if (lvl > height) break;

            // print null node as "N"
            if (node.data != -1) Console.Write(node.data + " ");
            else Console.Write("N ");

            // null nodes have no children
            if (node.data == -1) continue;

            if (node.left == null) q.Enqueue((new Node(-1), lvl + 1));
            else q.Enqueue((node.left, lvl + 1));

            if (node.right == null) q.Enqueue((new Node(-1), lvl + 1));
            else q.Enqueue((node.right, lvl + 1));
        }
    }

    // Driver Code
    static void Main() {
        int[] pre = { 1, 2, 4, 8, 9, 5, 3, 6, 7 };
        int[] post = { 8, 9, 4, 5, 2, 6, 7, 3, 1 };

        Node root = constructTree(pre, post);
        levelOrder(root);
    }
}
JavaScript
// Node Structure
class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

// Custom Queue implementation
class Queue {
    constructor() {
        this.items = [];
        this.frontIndex = 0;
    }

    push(element) {
        this.items.push(element);
    }

    pop() {
        if (this.isEmpty()) return null;
        return this.items[this.frontIndex++];
    }

    front() {
        return this.items[this.frontIndex];
    }

    isEmpty() {
        return this.frontIndex >= this.items.length;
    }
}

// Recursive function to construct binary
// tree from preorder and postorder
function constructTreeUtil(pre, post, preIndex, l, h, size, postMap) {
    if (preIndex.value >= size || l > h)
        return null;
    let root = new Node(pre[preIndex.value++]);

    // If there is only one element,
    // return it as leaf node
    if (l === h)
        return root;

    // Find the next preorder element
    // in postorder using hashmap
    let i = postMap.get(pre[preIndex.value]);

    if (i <= h) {
        root.left = constructTreeUtil(pre, post, preIndex,
                                                l, i, size, postMap);
                                                
        root.right = constructTreeUtil(pre, post, preIndex, 
                                         i + 1, h - 1, size, postMap);
    }

    return root;
}

// Function to construct Binary Tree 
// from preorder and postorder
function constructTree(pre, post) {
    let preIndex = { value: 0 };
    let size = pre.length;

    // Build hashmap for postorder element 
    let postMap = new Map();
    for (let i = 0; i < size; i++)
        postMap.set(post[i], i);

    return constructTreeUtil(pre, post, preIndex, 0,
                                   size - 1, size, postMap);
}

// Function to get the height of the tree
function getHeight(root, h) {
    if (root === null) return h - 1;
    return Math.max(getHeight(root.left, h + 1),
                           getHeight(root.right, h + 1));
}

// Level Order traversal
function levelOrder(root) {
    let q = new Queue();
    q.push([root, 0]);

    let lastLevel = 0;
    let height = getHeight(root, 0);

    while (!q.isEmpty()) {
        let [node, lvl] = q.pop();

        if (lvl > lastLevel) {
            console.log();
            lastLevel = lvl;
        }
        
         // all levels are printed
            if (lvl > height) break;

        // print null node as "N"
        if (node.data !== -1)
        process.stdout.write(node.data + " ");
        else 
        process.stdout.write("N ");

        // null nodes have no children
        if (node.data === -1) continue;

        if (node.left === null)
        q.push([new Node(-1), lvl + 1]);
        else 
        q.push([node.left, lvl + 1]);

        if (node.right === null) 
        q.push([new Node(-1), lvl + 1]);
        else
        q.push([node.right, lvl + 1]);
    }
}

// Driver Code 
let pre = [1, 2, 4, 8, 9, 5, 3, 6, 7];
let post = [8, 9, 4, 5, 2, 6, 7, 3, 1];

let root = constructTree(pre, post);
levelOrder(root);

Output
1 
2 3 
4 5 6 7 
8 9 N N N N N N 
Comment