Open In App

Construct Tree from given Inorder and Preorder traversals

Last Updated : 11 Jan, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given in-order and pre-order traversals of a Binary Tree, the task is to construct the Binary Tree and return its root.

Example:

Input: inorder[] = [3, 1, 4, 0, 5, 2], preorder[] = [0, 1, 3, 4, 2, 5]
Output: [0, 1, 2, 3, 4, 5]
Explanation: The tree will look like:

construct-tree-from-given-inorder-and-preorder-traversals

[Naive Approach] Using Pre-order traversal - O(n^2) Time and O(h) Space

The idea is to construct the tree using pre-order traversal. Take the first element of the pre-order array and create root node. Find the index of this node in the in-order array. Create the left subtree using the elements present on left side of root node in in-order array. Similarly create the right subtree using the elements present on the right side of the root node in in-order array.


C++
//Driver Code Starts
// c++ program to construct tree using
// inorder and preorder traversals
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

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

// Print tree as level order
void printLevelOrder(Node *root) {
    if (root == nullptr) {
        cout << "N ";
        return;
    }

    queue<Node *> qq;
    qq.push(root);
    int nonNull = 1;

    while (!qq.empty() && nonNull > 0) {
        Node *curr = qq.front();
        qq.pop();

        if (curr == nullptr) {
            cout << "N ";
            continue;
        }
        nonNull--;

        cout << (curr->data) << " ";
        qq.push(curr->left);
        qq.push(curr->right);
        if (curr->left)
            nonNull++;
        if (curr->right)
            nonNull++;
    }
}
//Driver Code Ends


// Function to find the index of an element in the array.
int search(vector<int> &inorder, int value, int left, int right) {

    for (int i = left; i <= right; i++) {
        if (inorder[i] == value)
            return i;
    }
    return -1;
}

// Recursive function to build the binary tree.
Node *buildTreeRecur(vector<int> &inorder, vector<int> &preorder, 
                     	int &preIndex, int left, int right) {

    // For empty inorder array, return null
    if (left > right)
        return nullptr;

    int rootVal = preorder[preIndex];
    preIndex++;

    // create the root Node
    Node *root = new Node(rootVal);

    // find the index of Root element in the in-order array.
    int index = search(inorder, rootVal, left, right);

    // Recursively create the left and right subtree.
    root->left = buildTreeRecur(inorder, preorder, preIndex, left, index - 1);
    root->right = buildTreeRecur(inorder, preorder, preIndex, index + 1, right);

    return root;
}

// Function to construct tree from its inorder and preorder traversals
Node *buildTree(vector<int> &inorder, vector<int> &preorder) {

    int preIndex = 0;
    Node *root = buildTreeRecur(inorder, preorder, preIndex, 0, preorder.size() - 1);

    return root;
}


//Driver Code Starts
int main() {
    vector<int> inorder = {3, 1, 4, 0, 5, 2};
    vector<int> preorder = {0, 1, 3, 4, 2, 5};
    Node *root = buildTree(inorder, preorder);

    printLevelOrder(root);

    return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
// Java program to construct tree using 
// inorder and preorder traversals
import java.util.Queue;
import java.util.LinkedList;

class Node {
    int data;
    Node left, right;

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

class GfG {

    // Print tree as level order
    static void printLevelOrder(Node root) {
        if (root == null) {
            System.out.print("N ");
            return;
        }

        Queue<Node> queue = new LinkedList<>();
        queue.add(root);
        int nonNull = 1;

        while (!queue.isEmpty() && nonNull > 0) {
            Node curr = queue.poll();

            if (curr == null) {
                System.out.print("N ");
                continue;
            }
            nonNull--;

            System.out.print(curr.data + " ");
            queue.add(curr.left);
            queue.add(curr.right);
            if (curr.left != null)
                nonNull++;
            if (curr.right != null)
                nonNull++;
        }
    }
//Driver Code Ends


    // Function to find the index of an element in the array.
    static int search(int[] inorder, int value, int left, int right) {
        for (int i = left; i <= right; i++) {
            if (inorder[i] == value)
                return i;
        }
        return -1;
    }

    // Recursive function to build the binary tree.
    static Node buildTreeRecur(int[] inorder, int[] preorder, int[] preIndex, int left, int right) {

        // For empty inorder array, return null
        if (left > right)
            return null;

        int rootVal = preorder[preIndex[0]];
        preIndex[0]++;

        // create the root Node
        Node root = new Node(rootVal);

        // find the index of Root element in the in-order array.
        int index = search(inorder, rootVal, left, right);

        // Recursively create the left and right subtree.
        root.left = buildTreeRecur(inorder, preorder, preIndex, left, index - 1);
        root.right = buildTreeRecur(inorder, preorder, preIndex, index + 1, right);

        return root;
    }


    // Function to construct tree from its inorder and preorder traversals
    static Node buildTree(int[] inorder, int[] preorder) {
        int[] preIndex = {0};
        return buildTreeRecur(inorder, preorder, preIndex, 0, preorder.length - 1);
    }


//Driver Code Starts
    public static void main(String[] args) {
        int[] inorder = {3, 1, 4, 0, 5, 2};
        int[] preorder = {0, 1, 3, 4, 2, 5};

        Node root = buildTree(inorder, preorder);
        printLevelOrder(root);
    }
}

//Driver Code Ends
Python
#Driver Code Starts
# Python program to construct tree using 
# inorder and preorder traversals

from collections import deque

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

# Print tree as level order
def printLevelOrder(root):
    if root is None:
        print("N ", end="")
        return

    queue = deque([root])
    non_null = 1

    while queue and non_null > 0:
        curr = queue.popleft()

        if curr is None:
            print("N ", end="")
            continue
        non_null -= 1

        print(curr.data, end=" ")
        queue.append(curr.left)
        queue.append(curr.right)
        if curr.left:
            non_null += 1
        if curr.right:
            non_null += 1
#Driver Code Ends


# Function to find the index of an element in the array
def search(inorder, value, left, right):
    for i in range(left, right + 1):
        if inorder[i] == value:
            return i
    return -1

# Recursive function to build the binary tree.
def buildTreeRecur(inorder, preorder, preIndex, left, right):
    # For empty inorder array, return null
    if left > right:
        return None

    rootVal = preorder[preIndex[0]]
    preIndex[0] += 1

    # create the root Node
    root = Node(rootVal)

    # find the index of Root element in the in-order array.
    index = search(inorder, rootVal, left, right)

    # Recursively create the left and right subtree.
    root.left = buildTreeRecur(inorder, preorder, preIndex, left, index - 1)
    root.right = buildTreeRecur(inorder, preorder, preIndex, index + 1, right)

    return root

# Function to construct tree from its inorder and preorder traversals
def buildTree(inorder, preorder):
    preIndex = [0]
    return buildTreeRecur(inorder, preorder, preIndex, 0, len(preorder) - 1)


#Driver Code Starts
if __name__ == "__main__":
    inorder = [3, 1, 4, 0, 5, 2]
    preorder = [0, 1, 3, 4, 2, 5]
    root = buildTree(inorder, preorder)
    printLevelOrder(root)

#Driver Code Ends
C#
//Driver Code Starts
// C# program to construct tree using 
// inorder and preorder traversals
using System;
using System.Collections.Generic;

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

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

class GfG {

    // Print tree as level order
    static void PrintLevelOrder(Node root) {
        if (root == null) {
            Console.Write("N ");
            return;
        }

        Queue<Node> queue = new Queue<Node>();
        queue.Enqueue(root);
        int nonNull = 1;

        while (queue.Count > 0 && nonNull > 0) {
            Node curr = queue.Dequeue();

            if (curr == null) {
                Console.Write("N ");
                continue;
            }
            nonNull--;

            Console.Write(curr.data + " ");
            queue.Enqueue(curr.left);
            queue.Enqueue(curr.right);
            if (curr.left != null)
                nonNull++;
            if (curr.right != null)
                nonNull++;
        }
    }
//Driver Code Ends


    // Function to find the index of an element in the array
    static int Search(int[] inorder, int value, int left, int right) {
        for (int i = left; i <= right; i++) {
            if (inorder[i] == value)
                return i;
        }
        return -1;
    }

    // Recursive function to build the binary tree.
    static Node BuildTreeRecur(int[] inorder, int[] preorder, 
                               ref int preIndex, int left, int right) {

        // For empty inorder array, return null
        if (left > right)
            return null;

        int rootVal = preorder[preIndex];
        preIndex++;

        // create the root Node
        Node root = new Node(rootVal);

        // find the index of Root element in the in-order array.
        int index = Search(inorder, rootVal, left, right);

        // Recursively create the left and right subtree.
        root.left = BuildTreeRecur(inorder, preorder, ref preIndex, left, index - 1);
        root.right = BuildTreeRecur(inorder, preorder, ref preIndex, index + 1, right);

        return root;
    }

    // Function to construct tree from its inorder and preorder traversals
    static Node BuildTree(int[] inorder, int[] preorder) {
        int preIndex = 0;
        return BuildTreeRecur(inorder, preorder, ref preIndex, 0, preorder.Length - 1);
    }


//Driver Code Starts
    static void Main(string[] args) {
        int[] inorder = { 3, 1, 4, 0, 5, 2 };
        int[] preorder = { 0, 1, 3, 4, 2, 5 };

        Node root = BuildTree(inorder, preorder);
        PrintLevelOrder(root);
    }
}

//Driver Code Ends
JavaScript
//Driver Code Starts
// JavaScript program to construct tree using 
// inorder and preorder traversals

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

// Print tree as level order
function printLevelOrder(root) {
    if (root === null) {
        process.stdout.write("N ");
        return;
    }

    const queue = [];
    queue.push(root);
    let nonNull = 1;

    while (queue.length > 0 && nonNull > 0) {
        const curr = queue.shift();

        if (curr === null) {
            process.stdout.write("N ");
            continue;
        }
        nonNull--;

        process.stdout.write(curr.data + " ");
        queue.push(curr.left);
        queue.push(curr.right);
        if (curr.left) nonNull++;
        if (curr.right) nonNull++;
    }
}
//Driver Code Ends


// Function to find the index of an element in the array
function search(inorder, value, left, right) {
    for (let i = left; i <= right; i++) {
        if (inorder[i] === value) return i;
    }
    return -1;
}

// Recursive function to build the binary tree.
function buildTreeRecur(inorder, preorder, preIndex, left, right) {

    // For empty inorder array, return null
    if (left > right)
        return null;

    const rootVal = preorder[preIndex[0]];
    preIndex[0]++;

    // create the root Node
    const root = new Node(rootVal);

    // find the index of Root element in the in-order array.
    const index = search(inorder, rootVal, left, right);

    // Recursively create the left and right subtree.
    root.left = buildTreeRecur(inorder, preorder, preIndex, left, index - 1);
    root.right = buildTreeRecur(inorder, preorder, preIndex, index + 1, right);

    return root;
}

// Function to construct tree from its inorder and preorder traversals
function buildTree(inorder, preorder) {
    const preIndex = [0];
    return buildTreeRecur(inorder, preorder, preIndex, 0, preorder.length - 1);
}


//Driver Code Starts
// Driver Code
const inorder = [3, 1, 4, 0, 5, 2];
const preorder = [0, 1, 3, 4, 2, 5];

const root = buildTree(inorder, preorder);
printLevelOrder(root);

//Driver Code Ends

Output
0 1 2 3 4 5 

[Expected Approach] Using Pre-order traversal and Hash map - O(n) Time and O(n) Space

The idea is similar to first approach, but instead of linearly searching the in-order array for each node we can use hashing. Map the values of in-order array to its indices. This will reduce the searching complexity from O(n) to O(1).

Below is the implementation of the above approach:

C++
//Driver Code Starts
// c++ program to construct tree using 
// inorder and preorder traversals
#include <iostream>
#include <queue>
#include <vector>
#include <unordered_map>
using namespace std;

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

// Print tree as level order
void printLevelOrder(Node *root) {
    if (root == nullptr) {
        cout << "N ";
        return;
    }

    queue<Node *> qq;
    qq.push(root);
    int nonNull = 1;

    while (!qq.empty() && nonNull > 0) {
        Node *curr = qq.front();
        qq.pop();

        if (curr == nullptr) {
            cout << "N ";
            continue;
        }
        nonNull--;

        cout << (curr->data) << " ";
        qq.push(curr->left);
        qq.push(curr->right);
        if (curr->left)
            nonNull++;
        if (curr->right)
            nonNull++;
    }
}
//Driver Code Ends


// Recursive function to build the binary tree.
Node *buildTreeRecur(unordered_map<int,int> &mp, vector<int> &preorder, 
                     	int &preIndex, int left, int right) {

    // For empty inorder array, return null
    if (left > right)
        return nullptr;

    int rootVal = preorder[preIndex];
    preIndex++;

    // create the root Node
    Node *root = new Node(rootVal);

    // find the index of Root element in the in-order array.
    int index = mp[rootVal];

    // Recursively create the left and right subtree.
    root->left = buildTreeRecur(mp, preorder, preIndex, left, index - 1);
    root->right = buildTreeRecur(mp, preorder, preIndex, index + 1, right);

    return root;
}

// Function to construct tree from its inorder and preorder traversals
Node *buildTree(vector<int> &inorder, vector<int> &preorder) {
	
  	// Hash map that stores index of a root element in inorder array
  	unordered_map<int,int> mp;
  	for (int i = 0; i < inorder.size(); i++) 
      	mp[inorder[i]] = i;
  
  	int preIndex = 0;
    Node *root = buildTreeRecur(mp, preorder, preIndex, 0, inorder.size() - 1);

    return root;
}


//Driver Code Starts
int main() {
    vector<int> inorder = {3, 1, 4, 0, 5, 2};
    vector<int> preorder = {0, 1, 3, 4, 2, 5};
    Node *root = buildTree(inorder, preorder);

    printLevelOrder(root);

    return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
// Java program to construct tree using 
// inorder and preorder traversals

import java.util.*;

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

class GfG {
	
	// Print tree as level order
    static void printLevelOrder(Node root) {
        if (root == null) {
            System.out.print("N ");
            return;
        }

        Queue<Node> qq = new LinkedList<>();
        qq.add(root);
        int nonNull = 1;

        while (!qq.isEmpty() && nonNull > 0) {
            Node curr = qq.poll();

            if (curr == null) {
                System.out.print("N ");
                continue;
            }
            nonNull--;

            System.out.print(curr.data + " ");
            qq.add(curr.left);
            qq.add(curr.right);
            if (curr.left != null)
                nonNull++;
            if (curr.right != null)
                nonNull++;
        }
    }
//Driver Code Ends


    // Recursive function to build the binary tree.
    static Node buildTreeRecur(Map<Integer, Integer> mp, int[] preorder, 
                               int[] preIndex, int left, int right) {

        // For empty inorder array, return null
        if (left > right)
            return null;

        int rootVal = preorder[preIndex[0]];
        preIndex[0]++;

        // create the root Node
        Node root = new Node(rootVal);

        // find the index of Root element in the in-order array.
        int index = mp.get(rootVal);

        // Recursively create the left and right subtree.
        root.left = buildTreeRecur(mp, preorder, preIndex, left, index - 1);
        root.right = buildTreeRecur(mp, preorder, preIndex, index + 1, right);

        return root;
    }

    // Function to construct tree from its inorder and preorder traversals
    static Node buildTree(int[] inorder, int[] preorder) {

        // Hash map that stores index of a root element in inorder array
        Map<Integer, Integer> mp = new HashMap<>();
        for (int i = 0; i < inorder.length; i++)
            mp.put(inorder[i], i);

        int[] preIndex = {0};
        return buildTreeRecur(mp, preorder, preIndex, 0, inorder.length - 1);
    }


//Driver Code Starts
    public static void main(String[] args) {
        int[] inorder = {3, 1, 4, 0, 5, 2};
        int[] preorder = {0, 1, 3, 4, 2, 5};
        Node root = buildTree(inorder, preorder);

        printLevelOrder(root);
    }
}

//Driver Code Ends
Python
#Driver Code Starts
# Python program to construct tree using 
# inorder and preorder traversals

from collections import deque

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

# Print tree as level order
def printLevelOrder(root):
    if root is None:
        print("N ", end="")
        return

    qq = deque([root])
    nonNull = 1

    while qq and nonNull > 0:
        curr = qq.popleft()

        if curr is None:
            print("N ", end="")
            continue
        nonNull -= 1

        print(curr.data, end=" ")
        qq.append(curr.left)
        qq.append(curr.right)
        if curr.left:
            nonNull += 1
        if curr.right:
            nonNull += 1
#Driver Code Ends


# Recursive function to build the binary tree.
def buildTreeRecur(mp, preorder, preIndex, left, right):
    # For empty inorder array, return None
    if left > right:
        return None

    rootVal = preorder[preIndex[0]]
    preIndex[0] += 1

    # create the root Node
    root = Node(rootVal)

    # find the index of Root element in the in-order array.
    index = mp[rootVal]

    # Recursively create the left and right subtree.
    root.left = buildTreeRecur(mp, preorder, preIndex, left, index - 1)
    root.right = buildTreeRecur(mp, preorder, preIndex, index + 1, right)

    return root

# Function to construct tree from its inorder and preorder traversals
def buildTree(inorder, preorder):
  
    # Hash map that stores index of a root element in inorder array
    mp = {value: idx for idx, value in enumerate(inorder)}
    preIndex = [0]
    
    return buildTreeRecur(mp, preorder, preIndex, 0, len(inorder) - 1)


#Driver Code Starts
if __name__ == "__main__":
    inorder = [3, 1, 4, 0, 5, 2]
    preorder = [0, 1, 3, 4, 2, 5]
    root = buildTree(inorder, preorder)

    printLevelOrder(root)

#Driver Code Ends
C#
//Driver Code Starts
// C# program to construct tree using 
// inorder and preorder traversals

using System;
using System.Collections.Generic;

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

class GfG {

    // Print tree as level order
    static void PrintLevelOrder(Node root) {
        if (root == null) {
            Console.Write("N ");
            return;
        }

        Queue<Node> qq = new Queue<Node>();
        qq.Enqueue(root);
        int nonNull = 1;

        while (qq.Count > 0 && nonNull > 0) {
            Node curr = qq.Dequeue();

            if (curr == null) {
                Console.Write("N ");
                continue;
            }
            nonNull--;

            Console.Write(curr.data + " ");
            qq.Enqueue(curr.left);
            qq.Enqueue(curr.right);
            if (curr.left != null)
                nonNull++;
            if (curr.right != null)
                nonNull++;
        }
    }
//Driver Code Ends


    // Recursive function to build the binary tree.
    static Node BuildTreeRecur(Dictionary<int, int> mp, int[] preorder, 
                               ref int preIndex, int left, int right) {

        // For empty inorder array, return null
        if (left > right)
            return null;

        int rootVal = preorder[preIndex];
        preIndex++;

        // create the root Node
        Node root = new Node(rootVal);

        // find the index of Root element in the in-order array.
        int index = mp[rootVal];

        // Recursively create the left and right subtree.
        root.left = BuildTreeRecur(mp, preorder, ref preIndex, left, index - 1);
        root.right = BuildTreeRecur(mp, preorder, ref preIndex, index + 1, right);

        return root;
    }

    // Function to construct tree from its inorder and preorder traversals
    static Node BuildTree(int[] inorder, int[] preorder) {

        // Hash map that stores index of a root element in inorder array
        Dictionary<int, int> mp = new Dictionary<int, int>();
        for (int i = 0; i < inorder.Length; i++)
            mp[inorder[i]] = i;

        int preIndex = 0;
        return BuildTreeRecur(mp, preorder, ref preIndex, 0, inorder.Length - 1);
    }


//Driver Code Starts
    public static void Main(string[] args) {
        int[] inorder = {3, 1, 4, 0, 5, 2};
        int[] preorder = {0, 1, 3, 4, 2, 5};
        Node root = BuildTree(inorder, preorder);

        PrintLevelOrder(root);
    }
}

//Driver Code Ends
JavaScript
//Driver Code Starts
// JavaScript program to construct tree using 
// inorder and preorder traversals

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

// Print tree as level order
function printLevelOrder(root) {
    if (root === null) {
        process.stdout.write("N ");
        return;
    }

    const qq = [];
    qq.push(root);
    let nonNull = 1;

    while (qq.length > 0 && nonNull > 0) {
        const curr = qq.shift();

        if (curr === null) {
            process.stdout.write("N ");
            continue;
        }
        nonNull--;

        process.stdout.write(curr.data + " ");
        qq.push(curr.left);
        qq.push(curr.right);
        if (curr.left !== null)
            nonNull++;
        if (curr.right !== null)
            nonNull++;
    }
}
//Driver Code Ends


// Recursive function to build the binary tree.
function buildTreeRecur(mp, preorder, preIndex, left, right) {

    // For empty inorder array, return null
    if (left > right)
        return null;

    const rootVal = preorder[preIndex[0]];
    preIndex[0]++;

    // create the root Node
    const root = new Node(rootVal);

    // find the index of Root element in the in-order array.
    const index = mp[rootVal];

    // Recursively create the left and right subtree.
    root.left = buildTreeRecur(mp, preorder, preIndex, left, index - 1);
    root.right = buildTreeRecur(mp, preorder, preIndex, index + 1, right);

    return root;
}

// Function to construct tree from its inorder and preorder traversals
function buildTree(inorder, preorder) {

    // Hash map that stores index of a root element in inorder array
    const mp = {};
    inorder.forEach((val, idx) => {
        mp[val] = idx;
    });

    const preIndex = [0];
    return buildTreeRecur(mp, preorder, preIndex, 0, inorder.length - 1);
}


//Driver Code Starts
// Driver Code
const inorder = [3, 1, 4, 0, 5, 2];
const preorder = [0, 1, 3, 4, 2, 5];
const root = buildTree(inorder, preorder);

printLevelOrder(root);

//Driver Code Ends

Output
0 1 2 3 4 5 

Related articles:


Next Article

Similar Reads