Construct a special tree from given preorder traversal - GeeksforGeeks

18 Apr, 2022
Given an array ‘pre[]’ that represents Preorder traversal of a special binary tree where every node has either 0 or 2 children. One more array ‘preLN[]’ is given which has only two possible values ‘L’ and ‘N’. The value ‘L’ in ‘preLN[]’ indicates that the corresponding node in Binary Tree is a leaf node and value ‘N’ indicates that the corresponding node is a non-leaf node. Write a function to construct the tree from the given two arrays.
Example: 
Input:  pre[] = {10, 30, 20, 5, 15},  preLN[] = {‘N’, ‘N’, ‘L’, ‘L’, ‘L’}Output: Root of following tree
          10
         /  \
      30   15
      /    \
   20     5
Approach: 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.  
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// A program to construct Binary Tree from preorder traversal#include<bits/stdc++.h> // A binary tree node structurestruct node{    int data;    struct node *left;    struct node *right;}; // Utility function to create a new Binary Tree nodestruct node* newNode (int data){    struct node *temp = new struct node;    temp->data = data;    temp->left = NULL;    temp->right = NULL;    return temp;} // A recursive function to create a Binary Tree from given pre[]// preLN[] arrays. The function returns root of tree. index_ptr is used// to update index values in recursive calls. index must be initially// passed as 0 */struct node *constructTreeUtil(int pre[], char preLN[], int *index_ptr, int n){    int index = *index_ptr; // store the current value of index in pre[]     // Base Case: All nodes are constructed    if (index == n)        return NULL;     // Allocate memory for this node and increment index for    // subsequent recursive calls    struct node *temp = newNode ( pre[index] );    (*index_ptr)++;     // If this is an internal node, construct left and right subtrees and link the subtrees    if (preLN[index] == 'N')    {      temp->left  = constructTreeUtil(pre, preLN, index_ptr, n);      temp->right = constructTreeUtil(pre, preLN, index_ptr, n);    }     return temp;} // A wrapper over constructTreeUtil()struct node *constructTree(int pre[], char preLN[], int n){    // Initialize index as 0. Value of index is used in recursion to maintain    // the current index in pre[] and preLN[] arrays.    int index = 0;     return constructTreeUtil (pre, preLN, &index, n);}  // This function is used only for testingvoid printInorder (struct node* node){    if (node == NULL)        return;     // First recur on left child    printInorder (node->left);     // Print the data of node    printf("%d ", node->data);     // Now recur on right child    printInorder (node->right);} // Driver codeint main(){    struct node *root = NULL;     /* Constructing tree given in the above figure          10         /  \        30   15       /  \      20   5 */    int pre[] = {10, 30, 20, 5, 15};    char preLN[] = {'N', 'N', 'L', 'L', 'L'};    int n = sizeof(pre)/sizeof(pre[0]);     // construct the above tree    root = constructTree (pre, preLN, n);     // Test the constructed tree    printf("Inorder Traversal of the Constructed Binary Tree: \n");    printInorder (root);     return 0;}
// Java program to construct a binary tree from preorder traversal  // A Binary Tree nodeclass Node{    int data;    Node left, right;      Node(int item)    {        data = item;        left = right = null;    }}  class Index{    int index = 0;}  class BinaryTree{    Node root;    Index myindex = new Index();      /* A recursive function to create a Binary Tree from given pre[]       preLN[] arrays. The function returns root of tree. index_ptr is used       to update index values in recursive calls. index must be initially       passed as 0 */    Node constructTreeUtil(int pre[], char preLN[], Index index_ptr,                                                     int n, Node temp)    {        // store the current value of index in pre[]        int index = index_ptr.index;          // Base Case: All nodes are constructed        if (index == n)            return null;          // Allocate memory for this node and increment index for        // subsequent recursive calls        temp = new Node(pre[index]);        (index_ptr.index)++;          // If this is an internal node, construct left and right subtrees        // and link the subtrees        if (preLN[index] == 'N')        {            temp.left = constructTreeUtil(pre, preLN, index_ptr, n,                                                               temp.left);            temp.right = constructTreeUtil(pre, preLN, index_ptr, n,                                                               temp.right);        }          return temp;    }      // A wrapper over constructTreeUtil()    Node constructTree(int pre[], char preLN[], int n, Node node)    {        // Initialize index as 0. Value of index is used in recursion to        // maintain the current index in pre[] and preLN[] arrays.        int index = 0;          return constructTreeUtil(pre, preLN, myindex, n, node);    }      /* This function is used only for testing */    void printInorder(Node node)    {        if (node == null)            return;          /* first recur on left child */        printInorder(node.left);          /* then print the data of node */        System.out.print(node.data + " ");          /* now recur on right child */        printInorder(node.right);    }      // driver function to test the above functions    public static void main(String args[])    {        BinaryTree tree = new BinaryTree();        int pre[] = new int[]{10, 30, 20, 5, 15};        char preLN[] = new char[]{'N', 'N', 'L', 'L', 'L'};        int n = pre.length;          // construct the above tree        Node mynode = tree.constructTree(pre, preLN, n, tree.root);          // Test the constructed tree        System.out.println("Following is Inorder Traversal of the"                                       + "Constructed Binary Tree: ");        tree.printInorder(mynode);    }}  // This code has been contributed by Mayank Jaiswal
# A program to construct Binary# Tree from preorder traversal # Utility function to create a# new Binary Tree nodeclass newNode:    def __init__(self, data):        self.data = data        self.left = None        self.right = None # A recursive function to create a# Binary Tree from given pre[] preLN[]# arrays. The function returns root of # tree. index_ptr is used to update# index values in recursive calls. index# must be initially passed as 0def constructTreeUtil(pre, preLN, index_ptr, n):         index = index_ptr[0] # store the current value                         # of index in pre[]     # Base Case: All nodes are constructed    if index == n:        return None     # Allocate memory for this node and    # increment index for subsequent    # recursive calls    temp = newNode(pre[index])    index_ptr[0] += 1     # If this is an internal node, construct left    # and right subtrees and link the subtrees    if preLN[index] == 'N':        temp.left = constructTreeUtil(pre, preLN,                                      index_ptr, n)        temp.right = constructTreeUtil(pre, preLN,                                       index_ptr, n)     return temp # A wrapper over constructTreeUtil()def constructTree(pre, preLN, n):         # Initialize index as 0. Value of index is    # used in recursion to maintain the current    # index in pre[] and preLN[] arrays.    index = [0]     return constructTreeUtil(pre, preLN, index, n) # This function is used only for testingdef printInorder (node):    if node == None:        return     # first recur on left child    printInorder (node.left)     # then print the data of node    print(node.data,end=" ")     # now recur on right child    printInorder (node.right)     # Driver Codeif __name__ == '__main__':    root = None     # Constructing tree given in    # the above figure    #     10    #     / \    # 30 15    # / \    # 20 5    pre = [10, 30, 20, 5, 15]    preLN = ['N', 'N', 'L', 'L', 'L']    n = len(pre)     # construct the above tree    root = constructTree (pre, preLN, n)     # Test the constructed tree    print("Following is Inorder Traversal of",          "the Constructed Binary Tree:")    printInorder (root)     # This code is contributed by PranchalK
// C# program to construct a binary// tree from preorder traversalusing System; // A Binary Tree nodepublic class Node{    public int data;    public Node left, right;     public Node(int item)    {        data = item;        left = right = null;    }} public class Index{    public int index = 0;} class GFG{public Node root;public Index myindex = new Index(); /* A recursive function to create aBinary Tree from given pre[] preLN[] arrays.The function returns root of tree. index_ptris used to update index values in recursivecalls. index must be initially passed as 0 */public virtual Node constructTreeUtil(int[] pre, char[] preLN,                                      Index index_ptr, int n,                                      Node temp){    // store the current value of index in pre[]    int index = index_ptr.index;     // Base Case: All nodes are constructed    if (index == n)    {        return null;    }     // Allocate memory for this node    // and increment index for    // subsequent recursive calls    temp = new Node(pre[index]);    (index_ptr.index)++;     // If this is an internal node,    // construct left and right subtrees    // and link the subtrees    if (preLN[index] == 'N')    {        temp.left = constructTreeUtil(pre, preLN, index_ptr,                                      n, temp.left);        temp.right = constructTreeUtil(pre, preLN, index_ptr,                                       n, temp.right);    }     return temp;} // A wrapper over constructTreeUtil()public virtual Node constructTree(int[] pre, char[] preLN,                                  int n, Node node){    // Initialize index as 0. Value of    // index is used in recursion to    // maintain the current index in    // pre[] and preLN[] arrays.    int index = 0;     return constructTreeUtil(pre, preLN,                             myindex, n, node);} /* This function is used only for testing */public virtual void printInorder(Node node){    if (node == null)    {        return;    }     /* first recur on left child */    printInorder(node.left);     /* then print the data of node */    Console.Write(node.data + " ");     /* now recur on right child */    printInorder(node.right);} // Driver Codepublic static void Main(string[] args){    GFG tree = new GFG();    int[] pre = new int[]{10, 30, 20, 5, 15};    char[] preLN = new char[]{'N', 'N', 'L', 'L', 'L'};    int n = pre.Length;     // construct the above tree    Node mynode = tree.constructTree(pre, preLN,                                     n, tree.root);     // Test the constructed tree    Console.WriteLine("Following is Inorder Traversal of the" +                                  "Constructed Binary Tree: ");    tree.printInorder(mynode);}} // This code is contributed by Shrikant13
<script>   // JavaScript program to construct a binary// tree from preorder traversal // A Binary Tree nodeclass Node{    constructor(item)    {        this.data = item;        this.left = null;        this.right = null;    }} class Index{    constructor()    {        this.index = 0;    }}  var root = null;var myindex = new Index(); /* A recursive function to create aBinary Tree from given pre[] preLN[] arrays.The function returns root of tree. index_ptris used to update index values in recursivecalls. index must be initially passed as 0 */function constructTreeUtil(pre, preLN, index_ptr, n, temp){    // store the current value of index in pre[]    var index = index_ptr.index;     // Base Case: All nodes are constructed    if (index == n)    {        return null;    }     // Allocate memory for this node    // and increment index for    // subsequent recursive calls    temp = new Node(pre[index]);    (index_ptr.index)++;     // If this is an internal node,    // construct left and right subtrees    // and link the subtrees    if (preLN[index] == 'N')    {        temp.left = constructTreeUtil(pre, preLN, index_ptr,                                      n, temp.left);        temp.right = constructTreeUtil(pre, preLN, index_ptr,                                       n, temp.right);    }     return temp;} // A wrapper over constructTreeUtil()function constructTree(pre, preLN, n, node){    // Initialize index as 0. Value of    // index is used in recursion to    // maintain the current index in    // pre[] and preLN[] arrays.    var index = 0;     return constructTreeUtil(pre, preLN,                             myindex, n, node);} /* This function is used only for testing */function printInorder( node){    if (node == null)    {        return;    }     /* first recur on left child */    printInorder(node.left);     /* then print the data of node */    document.write(node.data + " ");     /* now recur on right child */    printInorder(node.right);} // Driver Codevar pre = [10, 30, 20, 5, 15];var preLN = ['N', 'N', 'L', 'L', 'L'];var n = pre.length;// construct the above treevar mynode = constructTree(pre, preLN,                                 n, root);// Test the constructed treedocument.write("Following is Inorder Traversal of the" +                              "Constructed Binary Tree:<br>");printInorder(mynode);   </script>
Inorder Traversal of the Constructed Binary Tree: 
20 30 5 10 15 
Time Complexity: O(n)Auxiliary Space: O(n)
Method 2: Using Stack without recursion
Approach: 
As the Pre-order Traversal is given so we first make a root and insert the first value into it.
Traverse the given pre-order traversal.Check the left of stack’s topIf it  NULL then we add the present node on leftOtherwise, Add into right if right is NULL.If left and right both are not NULL, it means that the node have both left and right so we pop out the nodes until we won’t get any node whose left or right is NULL.If the present node is not a leaf node, push node into the stack.
Check the left of stack’s topIf it  NULL then we add the present node on leftOtherwise, Add into right if right is NULL.
If it  NULL then we add the present node on left
Otherwise, Add into right if right is NULL.
If left and right both are not NULL, it means that the node have both left and right so we pop out the nodes until we won’t get any node whose left or right is NULL.
If the present node is not a leaf node, push node into the stack.
Finally return the root of the constructed tree.
Below is the implementation of the above approach: 
C++
// A program to construct Binary Tree from preorder// traversal#include <bits/stdc++.h>using namespace std; // A binary tree node structurestruct node {    int data;    struct node* left;    struct node* right;    node(int x)    {        data = x;        left = right = NULL;    }}; struct node* constructTree(int pre[], char preLN[], int n){    // Taking an empty Stack    stack<node*> st;     // Setting up root node    node* root = new node(pre[0]);    // Checking if root is not leaf node    if (preLN[0] != 'L')        st.push(root);     // Iterating over the given node values    for (int i = 1; i < n; i++) {        node* temp = new node(pre[i]);         // Checking if the left position is NULL or not        if (!st.top()->left) {            st.top()->left = temp;             // Checking for leaf node            if (preLN[i] != 'L')                st.push(temp);        }         // Checking if the right position is NULL or not        else if (!st.top()->right) {            st.top()->right = temp;            if (preLN[i] != 'L')                 // Checking for leaf node                st.push(temp);        }         // If left and right of top node is already filles        else {            while (st.top()->left && st.top()->right)                st.pop();            st.top()->right = temp;             // Checking for leaf node            if (preLN[i] != 'L')                st.push(temp);        }    }     // Returning the root of tree    return root;} // This function is used only for testingvoid printInorder(struct node* node){    if (node == NULL)        return;     // First recur on left child    printInorder(node->left);     // Print the data of node    printf("%d ", node->data);     // Now recur on right child    printInorder(node->right);} // Driver codeint main(){    struct node* root = NULL;     /* Constructing tree given in the above figure          10         /  \        30   15       /  \      20   5 */    int pre[] = { 10, 30, 20, 5, 15 };    char preLN[] = { 'N', 'N', 'L', 'L', 'L' };    int n = sizeof(pre) / sizeof(pre[0]);     // construct the above tree    root = constructTree(pre, preLN, n);     // Test the constructed tree    printf("Inorder Traversal of the Constructed Binary Tree: \n");    printInorder(root);     return 0;} // This code is contributed by shubhamrajput6156
Inorder Traversal of the Constructed Binary Tree: 
20 30 5 10 15 
Time Complexity: O(n)Auxiliary Space: O(n)
Construct the full k-ary tree from its preorder traversalPlease write comments if you find anything incorrect, or you want to share more information about the topic discussed above
shrikanth13
PranchalKatiyar
rutvik_56
vatsaljain316
shubhamrajput6156
Amazon
Traversal
Tree
Amazon
Traversal
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Binary Tree | Set 3 (Types of Binary Tree)
Decision Tree
Binary Tree | Set 2 (Properties)
A program to check if a binary tree is BST or not
Complexity of different operations in Binary tree, Binary Search Tree and AVL tree
Introduction to Tree Data Structure
Lowest Common Ancestor in a Binary Tree | Set 1
Expression Tree
Binary Tree (Array implementation)
BFS vs DFS for Binary Tree