Construct a special tree from given preorder traversal

Last Updated : 15 Sep, 2026

Given two arrays pre[] and preLN[] of size n,

  • pre[] represents the preorder traversal of a  full binary tree (Every node has 0 or 2 Children).
  • preLN[i] stores 'L' if pre[i] is a leaf node and 'N' if a non-leaf node.

Construct the binary tree containing 'n' nodes.

Note: It is guaranteed that the given arrays represent a valid full binary tree and uniquely determine the constructed tree.

Example: 

Input:  pre[] = {10, 30, 20, 5, 15},  preLN[] = {'N', 'N', 'L', 'L', 'L'}
Output:

Construct-a-special-tree-from-given-preorder-traversal
Try It Yourself
redirect icon

[Expected Approach] Using Pre-Order Traversal - O(n) Time and O(h) Space

The first element in pre[] will always be root. So we can easily figure out the root.

If the left subtree is empty, the right subtree must also be empty, and the preLN[] entry for root must be ‘L’. We can simply create a node and return it.

If the left and right subtrees are not empty, then recursively call for left and right subtrees and link the returned nodes to root.  

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

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

// recursive function to construct the tree
Node* constructTreeRecur(int &index, vector<int>& pre, vector<char>& preLN) {
    Node* root = new Node(pre[index++]);

    // if the current node is a leaf node, return it directly
    if (preLN[index-1] == 'L')
        return root;

    // recursively create the left and right subtree
    root->left = constructTreeRecur(index, pre, preLN);
    root->right = constructTreeRecur(index, pre, preLN);

    return root;
}

Node* constructTree(vector<int>& pre, vector<char>& preLN) {
    int n = pre.size();

    // base case
    if (n == 0) return nullptr;

    int index = 0;
    return constructTreeRecur(index, pre, preLN);
}

void inorder(Node* root) {
    if (root == nullptr) return;
    inorder(root->left);
    cout << root->data << " ";
    inorder(root->right);
}

int main() {
    vector<int> pre = {10, 30, 20, 5, 15};
    vector<char> preLN = {'N', 'N', 'L', 'L', 'L'};

    Node* root = constructTree(pre, preLN);

    inorder(root);

    return 0;
}
Java
import java.util.*;

class Node {
    int data;
    Node left, right;

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

class GFG {
    static int index;

    // recursive function to construct the tree
    static Node constructTreeRecur(List<Integer> pre, List<Character> preLN) {
        Node root = new Node(pre.get(index++));

        // if the current node is a leaf node, return it directly
        if (preLN.get(index - 1) == 'L')
            return root;

        // recursively create the left and right subtree
        root.left = constructTreeRecur(pre, preLN);
        root.right = constructTreeRecur(pre, preLN);

        return root;
    }

    static Node constructTree(List<Integer> pre, List<Character> preLN) {
        int n = pre.size();

        // base case
        if (n == 0) return null;

        index = 0;
        return constructTreeRecur(pre, preLN);
    }

    static void inorder(Node root) {
        if (root == null) return;
        inorder(root.left);
        System.out.print(root.data + " ");
        inorder(root.right);
    }

    public static void main(String[] args) {
        List<Integer> pre = Arrays.asList(10, 30, 20, 5, 15);
        List<Character> preLN = Arrays.asList('N', 'N', 'L', 'L', 'L');

        Node root = constructTree(pre, preLN);

        inorder(root);
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None

index = 0

def constructTreeRecur(pre, preLN):
    global index
    root = Node(pre[index])
    index += 1

    # if the current node is a leaf node, return it directly
    if preLN[index - 1] == 'L':
        return root

    # recursively create the left and right subtree
    root.left = constructTreeRecur(pre, preLN)
    root.right = constructTreeRecur(pre, preLN)

    return root

def constructTree(pre, preLN):
    global index
    n = len(pre)

    # base case
    if n == 0:
        return None

    index = 0
    return constructTreeRecur(pre, preLN)

def inorder(root):
    if root is None:
        return
    inorder(root.left)
    print(root.data, end=" ")
    inorder(root.right)

pre = [10, 30, 20, 5, 15]
preLN = ['N', 'N', 'L', 'L', 'L']

root = constructTree(pre, preLN)
inorder(root)
C#
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 {
    static int index;

    // recursive function to construct the tree
    static Node constructTreeRecur(List<int> pre, List<char> preLN) {
        Node root = new Node(pre[index]);
        index++;

        // if the current node is a leaf node, return it directly
        if (preLN[index - 1] == 'L')
            return root;

        // recursively create the left and right subtree
        root.left = constructTreeRecur(pre, preLN);
        root.right = constructTreeRecur(pre, preLN);

        return root;
    }

    static Node constructTree(List<int> pre, List<char> preLN) {
        int n = pre.Count;

        // base case
        if (n == 0) return null;

        index = 0;
        return constructTreeRecur(pre, preLN);
    }

    static void Inorder(Node root) {
        if (root == null) return;
        Inorder(root.left);
        Console.Write(root.data + " ");
        Inorder(root.right);
    }

    static void Main() {
        List<int> pre = new List<int> { 10, 30, 20, 5, 15 };
        List<char> preLN = new List<char> { 'N', 'N', 'L', 'L', 'L' };

        Node root = constructTree(pre, preLN);

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

class GFG {
    // recursive function to construct the tree
    constructTreeRecur(pre, preLN, state) {
        const root = new Node(pre[state.index]);
        state.index++;

        // if the current node is a leaf node, return it directly
        if (preLN[state.index - 1] === 'L')
            return root;

        // recursively create the left and right subtree
        root.left = this.constructTreeRecur(pre, preLN, state);
        root.right = this.constructTreeRecur(pre, preLN, state);

        return root;
    }

    constructTree(pre, preLN) {
        const n = pre.length;

        // base case
        if (n === 0) return null;

        const state = { index: 0 };
        return this.constructTreeRecur(pre, preLN, state);
    }

    inorder(root) {
        if (root === null) return;
        this.inorder(root.left);
        process.stdout.write(root.data + " ");
        this.inorder(root.right);
    }
}

// Driver Code
const pre = [10, 30, 20, 5, 15];
const preLN = ['N', 'N', 'L', 'L', 'L'];

const gfg = new GfG();
const root = gfg.constructTree(pre, preLN);
gfg.inorder(root);

Output
20 30 5 10 15 

[Alternate Approach] Using Stack - O(n) Time and O(h) Space

The idea is to use a stack to implement Preorder traversal and construct the binary tree and return the root node.

Steps

Step 1: Create the root node from first element and insert it into an empty stack.

Step 2: Traverse the remaining preorder traversal.

  • Create the node corresponding to the current value.
  • Check the top node in the stack: If left of top node is null, then set the current node as left of top node. Else, right of top node is null, then set the current node as right of top node and pop the top node.
  • If the present node is not a leaf node, push node into the stack.

Step 3: Return the root of the constructed tree.

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

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

Node* constructTree(vector<int>& pre, vector<char>& preLN) {
    int n = pre.size();

    // base case
    if (n == 0) return nullptr;

    stack<Node*> st;
    Node* root = new Node(pre[0]);

    // checking if root is not a leaf node
    if (preLN[0] != 'L')
        st.push(root);

    // iterating over the given node values
    for (int i = 1; i < n; i++) {
        Node* curr = new Node(pre[i]);

        // checking if the left position is null
        if (!st.top()->left) {
            st.top()->left = curr;
        }
        // checking if the right position is null
        else if (!st.top()->right) {
            st.top()->right = curr;
            st.pop();
        }

        // if current node is an internal node, push it to the stack
        if (preLN[i] != 'L')
            st.push(curr);
    }

    return root;
}

void inorder(Node* root) {
    if (root == nullptr) return;
    inorder(root->left);
    cout << root->data << " ";
    inorder(root->right);
}

int main() {
    vector<int> pre = {10, 30, 20, 5, 15};
    vector<char> preLN = {'N', 'N', 'L', 'L', 'L'};

    Node* root = constructTree(pre, preLN);

    inorder(root);

    return 0;
}
Java
import java.util.*;

class Node {
    int data;
    Node left, right;

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

class GFG {
    static Node constructTree(List<Integer> pre, List<Character> preLN) {
        int n = pre.size();

        // base case
        if (n == 0) return null;

        Stack<Node> st = new Stack<>();
        Node root = new Node(pre.get(0));

        // checking if root is not a leaf node
        if (preLN.get(0) != 'L')
            st.push(root);

        // iterating over the given node values
        for (int i = 1; i < n; i++) {
            Node curr = new Node(pre.get(i));

            // checking if the left position is null
            if (st.peek().left == null) {
                st.peek().left = curr;
            }
            // checking if the right position is null
            else if (st.peek().right == null) {
                st.peek().right = curr;
                st.pop();
            }

            // if current node is an internal node, push it to the stack
            if (preLN.get(i) != 'L')
                st.push(curr);
        }

        return root;
    }

    static void inorder(Node root) {
        if (root == null) return;
        inorder(root.left);
        System.out.print(root.data + " ");
        inorder(root.right);
    }

    public static void main(String[] args) {
        List<Integer> pre = Arrays.asList(10, 30, 20, 5, 15);
        List<Character> preLN = Arrays.asList('N', 'N', 'L', 'L', 'L');

        Node root = constructTree(pre, preLN);

        inorder(root);
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None

def constructTree(pre, preLN):
    n = len(pre)

    # base case
    if n == 0:
        return None

    st = []
    root = Node(pre[0])

    # checking if root is not a leaf node
    if preLN[0] != 'L':
        st.append(root)

    # iterating over the given node values
    for i in range(1, n):
        curr = Node(pre[i])

        # checking if the left position is null
        if st[-1].left is None:
            st[-1].left = curr
        # checking if the right position is null
        elif st[-1].right is None:
            st[-1].right = curr
            st.pop()

        # if current node is an internal node, push it to the stack
        if preLN[i] != 'L':
            st.append(curr)

    return root

def inorder(root):
    if root is None:
        return
    inorder(root.left)
    print(root.data, end=" ")
    inorder(root.right)

pre = [10, 30, 20, 5, 15]
preLN = ['N', 'N', 'L', 'L', 'L']

root = constructTree(pre, preLN)
inorder(root)
C#
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 {
    static Node constructTree(List<int> pre, List<char> preLN) {
        int n = pre.Count;

        // base case
        if (n == 0) return null;

        Stack<Node> st = new Stack<Node>();
        Node root = new Node(pre[0]);

        // checking if root is not a leaf node
        if (preLN[0] != 'L')
            st.Push(root);

        // iterating over the given node values
        for (int i = 1; i < n; i++) {
            Node curr = new Node(pre[i]);

            // checking if the left position is null
            if (st.Peek().left == null) {
                st.Peek().left = curr;
            }
            // checking if the right position is null
            else if (st.Peek().right == null) {
                st.Peek().right = curr;
                st.Pop();
            }

            // if current node is an internal node, push it to the stack
            if (preLN[i] != 'L')
                st.Push(curr);
        }

        return root;
    }

    static void inorder(Node root) {
        if (root == null) return;
        inorder(root.left);
        Console.Write(root.data + " ");
        inorder(root.right);
    }

    static void Main() {
        List<int> pre = new List<int> { 10, 30, 20, 5, 15 };
        List<char> preLN = new List<char> { 'N', 'N', 'L', 'L', 'L' };

        Node root = constructTree(pre, preLN);

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

function constructTree(pre, preLN) {
    const n = pre.length;

    // base case
    if (n === 0) return null;

    const st = [];
    const root = new Node(pre[0]);

    // checking if root is not a leaf node
    if (preLN[0] !== 'L')
        st.push(root);

    // iterating over the given node values
    for (let i = 1; i < n; i++) {
        const curr = new Node(pre[i]);

        // checking if the left position is null
        if (st[st.length - 1].left === null) {
            st[st.length - 1].left = curr;
        }
        // checking if the right position is null
        else if (st[st.length - 1].right === null) {
            st[st.length - 1].right = curr;
            st.pop();
        }

        // if current node is an internal node, push it to the stack
        if (preLN[i] !== 'L')
            st.push(curr);
    }

    return root;
}

// Driver Code
function inorder(root) {
    if (root === null) return;
    inorder(root.left);
    process.stdout.write(root.data + " ");
    inorder(root.right);
}

const pre = [10, 30, 20, 5, 15];
const preLN = ['N', 'N', 'L', 'L', 'L'];

const root = constructTree(pre, preLN);

inorder(root);

Output
20 30 5 10 15 

Related article:

Comment