Construct BST from Preorder Traversal (original) (raw)

Given the preorder traversal of a binary search tree, construct the BST.

**Examples:

**Input: arr[] = [40, 30, 35, 80, 100]

blobid0_1777091399

**Output: [35, 30, 100, 80, 40]
**Explanation: PreOrder: 40 30 35 80 100

**Input: [10, 5, 1, 7, 40, 50]
**Output:

Construct-BST-from-Preorder-Traversal-1

**Explanation: The constructed tree is BST and if we do preorder traversal of it, we get the same array

Table of Content

[Naive Approach] Using One by One Insert - O(n log n) Time O(1) Space

1. Create an empty BST
2. Traverse through the given pre array and one by one insert every item into the BST

C++ `

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

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

// Function to insert a key into BST Node *insertBST(Node *root, int key) { Node *newNode = new Node(key); if (root == nullptr) return newNode; Node *curr = root; Node *parent = nullptr; while (curr != nullptr) { parent = curr; if (key < curr->data) curr = curr->left; else curr = curr->right; } if (key < parent->data) parent->left = newNode; else parent->right = newNode;

return root;

}

// Function to construct BST from preorder traversal Node *preToBST(vector &pre) { Node *root = nullptr;

// Insert elements one by one into BST
for (int x : pre)
{
    root = insertBST(root, x);
}

return root;

}

// Driver Code int main() { vector pre = {40, 30, 35, 80, 100};

Node *root = preToBST(pre);

// Function to print Postorder traversal
function<void(Node *)> postorder = [&](Node *node) {
    if (node == nullptr)
        return;

    postorder(node->left);
    postorder(node->right);
    cout << node->data << " ";
};

postorder(root);

return 0;

}

C

#include <stdio.h> #include <stdlib.h>

typedef struct Node { int data; struct Node *left, *right; } Node;

Node* insertBST(Node* root, int key) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = key; newNode->left = newNode->right = NULL;

if (root == NULL)
    return newNode;

Node* curr = root;
Node* parent = NULL;

while (curr!= NULL) {
    parent = curr;
    if (key < curr->data)
        curr = curr->left;
    else
        curr = curr->right;
}

if (key < parent->data)
    parent->left = newNode;
else
    parent->right = newNode;

return root;

}

Node* preToBST(int pre[], int n) { Node* root = NULL;

for (int i = 0; i < n; i++) {
    root = insertBST(root, pre[i]);
}

return root;

}

void postorder(Node* node) { if (node == NULL) return;

postorder(node->left);
postorder(node->right);
printf("%d ", node->data);

}

int main() { int pre[] = {40, 30, 35, 80, 100}; int n = sizeof(pre) / sizeof(pre[0]);

Node* root = preToBST(pre, n);

postorder(root);

return 0;

}

Java

import java.util.Arrays;

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

// Constructor
public Node(int val) {
    data = val;
    left = right = null;
}

}

public class Main { public static Node insertBST(Node root, int key) { Node newNode = new Node(key);

    if (root == null)
        return newNode;

    Node curr = root;
    Node parent = null;

    while (curr!= null) {
        parent = curr;
        if (key < curr.data)
            curr = curr.left;
        else
            curr = curr.right;
    }

    if (key < parent.data)
        parent.left = newNode;
    else
        parent.right = newNode;

    return root;
}

public static Node preToBST(int[] pre) {
    Node root = null;

    for (int x : pre) {
        root = insertBST(root, x);
    }

    return root;
}

public static void postorder(Node node) {
    if (node == null)
        return;

    postorder(node.left);
    postorder(node.right);
    System.out.print(node.data + " ");
}

public static void main(String[] args) {
    int[] pre = {40, 30, 35, 80, 100};

    Node root = preToBST(pre);

    postorder(root);
}

}

Python

class Node: def init(self, val): self.data = val self.left = self.right = None

def insertBST(root, key): newNode = Node(key)

if root is None:
    return newNode

curr = root
parent = None

while curr is not None:
    parent = curr
    if key < curr.data:
        curr = curr.left
    else:
        curr = curr.right

if key < parent.data:
    parent.left = newNode
else:
    parent.right = newNode

return root

def preToBST(pre): root = None

for x in pre:
    root = insertBST(root, x)

return root

def postorder(node): if node is None: return

postorder(node.left)
postorder(node.right)
print(node.data, end=' ')

This ensures main runs only when file is executed directly

if name == "main":

Driver Code

pre = [40, 30, 35, 80, 100]

root = preToBST(pre)

postorder(root)

JavaScript

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

function insertBST(root, key) { const newNode = new Node(key);

if (root === null)
    return newNode;

let curr = root;
let parent = null;

while (curr!== null) {
    parent = curr;
    if (key < curr.data)
        curr = curr.left;
    else
        curr = curr.right;
}

if (key < parent.data)
    parent.left = newNode;
else
    parent.right = newNode;

return root;

}

function preToBST(pre) { let root = null;

for (const x of pre) {
    root = insertBST(root, x);
}

return root;

}

// Driver Code { // Input preorder array const pre = [40, 30, 35, 80, 100];

let root = preToBST(pre);

// Function to print Postorder traversal
const postorder = (node) => {
    if (node === null)
        return;

    postorder(node.left);
    postorder(node.right);
    console.log(node.data + " ");
};

postorder(root);

}

`

**Time Complexity: O(n log n)
**Space Complexity: O(h)

[Better Approach] Using Find First Greater than Root **- O(n²) **Time O(h) **Space

The first element of preorder traversal is always the root. We first construct the root. Then we find the index of the first element which is greater than the root. Let the index be 'i'. The values between root (lowest index) and 'i' will be part of the left subtree, and the values between 'i'(inclusive) and 'n-1' will be part of the right subtree. Divide the given pre[] at index "i" and recur for left and right sub-trees.

**For example in {10, 5, 1, 7, 40, 50}, 10 is the first element, so we make it root. Now we look for the first element greater than 10, we find 40. So we know the structure of BST is as follows.:

wqew

We recursively follow the above steps for subarrays {5, 1, 7} and {40, 50}, and get the complete tree.

C++ `

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

class Node { public: int data; Node *left; Node *right;

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

};

// Helper function to construct BST from preorder // using range [low, high] Node *constructUtil(vector &pre, int low, int high) {

// Base Case: If range is invalid, return NULL
if (low > high)
    return nullptr;

// Create root node with first element
// of current subarray
Node *root = new Node(pre[low]);

// If only one element is present,
// return the root
if (low == high)
    return root;

// Find the first element greater than root
// to divide left and right subtrees
int i;
for (i = low + 1; i <= high; i++)
{
    if (pre[i] > root->data)
        break;
}

// Recursively construct the left subtree
// using elements smaller than root
root->left = constructUtil(pre, low + 1, i - 1);

// Recursively construct the right subtree
// using elements greater than root
root->right = constructUtil(pre, i, high);

// Return the constructed root
return root;

}

// Function to construct BST from preorder traversal Node *preToBST(vector &pre) {

// Call helper function with full range
return constructUtil(pre, 0, pre.size() - 1);

}

// Driver code int main() { vector pre = {40, 30, 35, 80, 100};

Node* root = preToBST(pre);

// Function to print Postorder traversal
function<void(Node*)> postOrder = [&](Node* root) {
    if (root == NULL)
        return;
    
    postOrder(root->left);
    postOrder(root->right);
    cout << root->data << " ";
};

postOrder(root);

return 0;

}

C

#include <stdio.h> #include <stdlib.h>

// Node structure struct Node { int data; struct Node *left; struct Node *right; };

// Helper function to create new Node struct Node* newNode(int data) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = data; node->left = NULL; node->right = NULL; return node; }

// Helper function to construct BST from preorder // using range [low, high] struct Node* constructUtil(int pre[], int low, int high) { // Base Case: If range is invalid, return NULL if (low > high) return NULL;

// Create root node with first element
// of current subarray
struct Node* root = newNode(pre[low]);

// If only one element is present,
// return the root
if (low == high)
    return root;

// Find the first element greater than root
// to divide left and right subtrees
int i;
for (i = low + 1; i <= high; i++)
if (pre[i] > root->data)
    break;

// Recursively construct the left subtree
// using elements smaller than root
root->left = constructUtil(pre, low + 1, i - 1);

// Recursively construct the right subtree
// using elements greater than root
root->right = constructUtil(pre, i, high);

// Return the constructed root
return root;

}

// Function to construct BST from preorder traversal struct Node* preToBST(int pre[], int size) { // Call helper function with full range return constructUtil(pre, 0, size - 1); }

// Function to print Postorder traversal void postOrder(struct Node* root) { if (root == NULL) return; postOrder(root->left); postOrder(root->right); printf("%d ", root->data); }

// Driver code int main() { // Input preorder array int pre[] = {40, 30, 35, 80, 100}; int size = sizeof(pre) / sizeof(pre[0]); struct Node* root = preToBST(pre, size); postOrder(root); return 0; }

Java

import java.util.*;

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

class GfG {

// Helper function to construct BST from preorder
// using index range [low, high]
public static Node constructUtil(int[] pre, int low, int high) {

    // Base case: invalid range
    if (low > high)
        return null;

    // First element in current range is root
    Node root = new Node(pre[low]);

    // If only one element, return node
    if (low == high)
        return root;

    int i;

    // Find first element greater than root
    // This divides left and right subtree
    for (i = low + 1; i <= high; i++) {
        if (pre[i] > root.data)
            break;
    }

    // Elements smaller than root → left subtree
    root.left = constructUtil(pre, low + 1, i - 1);

    // Elements greater than root → right subtree
    root.right = constructUtil(pre, i, high);

    return root;
}

// Main function to build BST from preorder array
public static Node preToBST(int[] pre) {

    // Call helper with full array range
    return constructUtil(pre, 0, pre.length - 1);
}

// Postorder traversal (Left → Right → Root)
public static void postOrder(Node root) {
    if (root == null)
        return;

    postOrder(root.left);
    postOrder(root.right);

    System.out.print(root.data + " ");
}

// Driver code
public static void main(String[] args) {

    int[] pre = {40, 30, 35, 80, 100};
  
    Node root = preToBST(pre);
    postOrder(root);
}

}

Python

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

def constructUtil(pre, low, high): if low > high: return None

root = Node(pre[low])

if low == high:
    return root

i = low + 1
while i <= high and pre[i] <= root.data:
    i += 1

root.left = constructUtil(pre, low + 1, i - 1)
root.right = constructUtil(pre, i, high)

return root

def preToBST(pre): return constructUtil(pre, 0, len(pre) - 1)

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

if name == 'main': pre = [40, 30, 35, 80, 100]

root = preToBST(pre)
postOrder(root)

JavaScript

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

function constructUtil(pre, low, high) { if (low > high) return null;

let root = new Node(pre[low]);
if (low == high)
    return root;

let i = low + 1;
while (i <= high) {
    if (pre[i] > root.data)
        break;
    i += 1;
}

root.left = constructUtil(pre, low + 1, i - 1);
root.right = constructUtil(pre, i, high);

return root;

}

function preToBST(pre) { return constructUtil(pre, 0, pre.length - 1); }

function postOrder(root) { if (root == null) return; postOrder(root.left); postOrder(root.right); console.log(root.data + ' '); }

let pre = [40, 30, 35, 80, 100]; let root = preToBST(pre); postOrder(root);

`

**Time Complexity: O(n2)
**Auxiliary Space: O(n)

[Efficient Approach 1] Pass Range in Recursion - O(n) Time O(h) Space

The trick is to set a range {min .. max} for every node. We initialize range as [-inf, +inf]. We begin with the first element of the preorder traversal, create a node with the given key. Now moving forward, we set the range as [-inf, key] for left subtree and [key, inf] for right subtree.

Follow the below steps to solve the problem:

C++ `

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

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

Node(int val)
{
    data = val;
    left = right = nullptr;
}

};

// A recursive function to construct BST from pre[]. // idx is used to keep track of index in pre[]. Node *constructUtil(vector &pre, int &idx, int min, int max) { if (idx >= pre.size()) return nullptr;

int key = pre[idx];
if (key <= min || key >= max)
    return nullptr;

// If current element of pre[] is in range,
// then only it is part of the current subtree
Node *root = new Node(key);
idx++;

// All nodes in range {min .. key}
// go to the left subtree
if (idx < pre.size())
    root->left = constructUtil(pre, idx, min, key);

// All nodes in range {key .. max}
// go to the right subtree
if (idx < pre.size())
    root->right = constructUtil(pre, idx, key, max);

return root;

}

// The main function to construct BST from // given preorder traversal. Node *preToBST(vector &pre) { int idx = 0; return constructUtil(pre, idx, INT_MIN, INT_MAX); }

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

// Driver code int main() { vector pre = {40, 30, 35, 80, 100}; Node *root = preToBST(pre);

postorder(root);

return 0;

}

C

#include <stdio.h> #include <stdlib.h> #include <limits.h>

// Structure of a tree node struct Node { int data; struct Node *left, *right; };

// Function to create a new node struct Node* newNode(int val) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = val; node->left = node->right = NULL; return node; }

// A recursive function to construct BST from preorder. // idx is used to keep track of index in preorder array. struct Node* constructUtil(int pre[], int size, int *idx, int min, int max) {

// Base case
if (*idx >= size)
    return NULL;

int key = pre[*idx];

// If current element is not in range, return NULL
if (key <= min || key >= max)
    return NULL;

// Create root node
struct Node* root = newNode(key);
(*idx)++;

// Construct left subtree
if (*idx < size)
    root->left = constructUtil(pre, size, idx, min, key);

// Construct right subtree
if (*idx < size)
    root->right = constructUtil(pre, size, idx, key, max);

return root;

}

// Function to construct BST from preorder traversal struct Node* preToBST(int pre[], int size) { int idx = 0; return constructUtil(pre, size, &idx, INT_MIN, INT_MAX); }

// Function to print postorder traversal void postorder(struct Node* root) { if (root == NULL) return; postorder(root->left); postorder(root->right); printf("%d ", root->data); }

// Driver code int main() { int pre[] = {40, 30, 35, 80, 100}; int size = sizeof(pre)/sizeof(pre[0]);

struct Node* root = preToBST(pre, size);

postorder(root);
return 0;

}

Java

import java.util.*;

// Class representing a node of BST class Node { int data; Node left, right;

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

}

class Solution {

// A recursive function to construct BST from preorder
// idx is passed as array to simulate pass by reference
public static Node constructUtil(int[] pre, int[] idx, int min, int max) {

    // Base case
    if (idx[0] >= pre.length)
        return null;

    int key = pre[idx[0]];

    // If key is not in valid range
    if (key <= min || key >= max)
        return null;

    // Create root node
    Node root = new Node(key);
    idx[0]++;

    // Construct left subtree
    if (idx[0] < pre.length)
        root.left = constructUtil(pre, idx, min, key);

    // Construct right subtree
    if (idx[0] < pre.length)
        root.right = constructUtil(pre, idx, key, max);

    return root;
}

// Function to construct BST
public static Node preToBST(int[] pre) {
    int[] idx = new int[1];
    return constructUtil(pre, idx, Integer.MIN_VALUE, Integer.MAX_VALUE);
}

// Function to print postorder traversal
public static void postorder(Node root) {
    if (root == null)
        return;
    postorder(root.left);
    postorder(root.right);
    System.out.print(root.data + " ");
}

public static void main(String[] args) {
    int[] pre = {40, 30, 35, 80, 100};
    Node root = preToBST(pre);

    postorder(root);
}

}

Python

Class representing a node

class Node: def init(self, val): self.data = val self.left = None self.right = None

A recursive function to construct BST from preorder

def constructUtil(pre, idx, min_val, max_val):

# Base case
if idx[0] >= len(pre):
    return None

key = pre[idx[0]]

# If key is not in range
if key <= min_val or key >= max_val:
    return None

# Create root node
root = Node(key)
idx[0] += 1

# Construct left subtree
if idx[0] < len(pre):
    root.left = constructUtil(pre, idx, min_val, key)

# Construct right subtree
if idx[0] < len(pre):
    root.right = constructUtil(pre, idx, key, max_val)

return root

Function to construct BST

def preToBST(pre): idx = [0] return constructUtil(pre, idx, float('-inf'), float('inf'))

Function to print postorder traversal

def postorder(root): if not root: return postorder(root.left) postorder(root.right) print(root.data, end=" ")

Driver code

pre = [40, 30, 35, 80, 100] root = preToBST(pre)

postorder(root)

C#

using System;

// Class representing a node class Node { public int data; public Node left, right;

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

}

class Program {

// Recursive function to construct BST
static Node constructUtil(int[] pre, ref int idx, int min, int max) {

    // Base case
    if (idx >= pre.Length)
        return null;

    int key = pre[idx];

    // If not in range
    if (key <= min || key >= max)
        return null;

    // Create node
    Node root = new Node(key);
    idx++;

    // Construct left subtree
    if (idx < pre.Length)
        root.left = constructUtil(pre, ref idx, min, key);

    // Construct right subtree
    if (idx < pre.Length)
        root.right = constructUtil(pre, ref idx, key, max);

    return root;
}

// Function to construct BST
static Node preToBST(int[] pre) {
    int idx = 0;
    return constructUtil(pre, ref idx, int.MinValue, int.MaxValue);
}

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

static void Main() {
    int[] pre = {40, 30, 35, 80, 100};
    Node root = preToBST(pre);

    postorder(root);
}

}

JavaScript

// Class representing a node class Node { constructor(val) { this.data = val; this.left = null; this.right = null; } }

// Recursive function to construct BST function constructUtil(pre, idx, min, max) {

// Base case
if (idx.value >= pre.length)
    return null;

let key = pre[idx.value];

// If not in range
if (key <= min || key >= max)
    return null;

// Create node
let root = new Node(key);
idx.value++;

// Construct left subtree
if (idx.value < pre.length)
    root.left = constructUtil(pre, idx, min, key);

// Construct right subtree
if (idx.value < pre.length)
    root.right = constructUtil(pre, idx, key, max);

return root;

}

// Function to construct BST function preToBST(pre) { let idx = { value: 0 }; return constructUtil(pre, idx, -Infinity, Infinity); }

// Postorder traversal function postorder(root) { if (!root) return; postorder(root.left); postorder(root.right); console.log(root.data + " "); }

// Driver code let pre = [40, 30, 35, 80, 100]; let root = preToBST(pre);

postorder(root);

`

**Time Complexity: O(n)
**Auxiliary Space: O(n)

[Expected Approach - 2] Using Stack - O(n) Time O(h) Space

The Idea is that the first element of preorder traversal is always the root. We create the root node and push it into a stack. The stack is used to keep track of nodes whose right child is not yet assigned.

Now for every next element in preorder:

After attaching, we push the current node into the stack.

C++ `

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

// Class definition for a tree node class Node { public: int data; Node *left; Node *right; Node(int val) { data = val; left = nullptr; right = nullptr; } };

Node *preToBST(vector &pre) {

int n = pre.size();

// Stack to keep track of ancestors
stack<Node *> st;

// First element is root
Node *root = new Node(pre[0]);
st.push(root);

// Process remaining elements
for (int i = 1; i < n; i++)
{

    // To store last popped node
    Node *temp = nullptr;

    // Find correct parent by popping smaller elements
    while (!st.empty() && pre[i] > st.top()->data)
    {
        temp = st.top();
        st.pop();
    }

    // If popped, attach as right child
    if (temp != nullptr)
    {
        temp->right = new Node(pre[i]);
        st.push(temp->right);
    }
    else
    {
        // Else attach as left child
        st.top()->left = new Node(pre[i]);
        st.push(st.top()->left);
    }
}

return root;

}

void postorder(Node* root) { if (!root) return; postorder(root->left); postorder(root->right); cout << root->data << " "; }

// Driver code int main() { vector arr = {40, 30, 35, 80, 100};

Node *root = preToBST(arr);

postorder(root);

return 0;

}

C

#include <stdio.h> #include <stdlib.h> #include <stdbool.h>

// Class definition for a tree node typedef struct Node { int data; struct Node *left; struct Node *right; } Node;

// Constructor to initialize node Node* newNode(int val) { Node* node = (Node*)malloc(sizeof(Node)); node->data = val; node->left = NULL; node->right = NULL; return node; }

Node* preToBST(int pre[], int n) { // Stack to keep track of ancestors Node** st = (Node**)malloc(n * sizeof(Node*)); int top = -1;

// First element is root Node* root = newNode(pre[0]); st[++top] = root;

// Process remaining elements for (int i = 1; i < n; i++) { Node* temp = NULL; // Find correct parent by popping smaller elements while (top >= 0 && pre[i] > st[top]->data) { temp = st[top--]; } // If popped, attach as right child if (temp!= NULL) { temp->right = newNode(pre[i]); st[++top] = temp->right; } else { // Else attach as left child st[top]->left = newNode(pre[i]); st[++top] = st[top]->left; } } free(st); return root; }

void postorder(Node* root) { if (!root) return; postorder(root->left); postorder(root->right); printf("%d ", root->data); }

// Driver code int main() { int arr[] = {40, 30, 35, 80, 100}; int n = sizeof(arr) / sizeof(arr[0]); Node* root = preToBST(arr, n); postorder(root); return 0; }

Java

import java.util.Stack;

// Class definition for a tree node class Node { public int data; public Node left; public Node right; public Node(int val) { data = val; left = null; right = null; } }

public class GFG { public static Node preToBST(int[] pre) { int n = pre.length;

// Stack to keep track of ancestors
Stack<Node> st = new Stack<>();

// First element is root
Node root = new Node(pre[0]);
st.push(root);

// Process remaining elements
for (int i = 1; i < n; i++) {
  Node temp = null;
  // Find correct parent by popping smaller elements
  while (!st.isEmpty() && pre[i] > st.peek().data) {
    temp = st.pop();
  }
  // If popped, attach as right child
  if (temp!= null) {
    temp.right = new Node(pre[i]);
    st.push(temp.right);
  }
  else {
    // Else attach as left child
    st.peek().left = new Node(pre[i]);
    st.push(st.peek().left);
  }
}
return root;

}

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

public static void main(String[] args) { int[] arr = {40, 30, 35, 80, 100}; Node root = preToBST(arr); postorder(root); } }

Python

from typing import List, Optional from collections import deque

Class definition for a tree node

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

def preToBST(pre: List[int]) -> Optional[Node]: n = len(pre)

Stack to keep track of ancestors

st = deque()

First element is root

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

Process remaining elements

for i in range(1, n): temp = None # Find correct parent by popping smaller elements while st and pre[i] > st[-1].data: temp = st.pop()

# If popped, attach as right child
if temp is not None:
  temp.right = Node(pre[i])
  st.append(temp.right)
else:
  # Else attach as left child
  st[-1].left = Node(pre[i])
  st.append(st[-1].left)

return root

def postorder(root: Optional[Node]): if not root: return postorder(root.left) postorder(root.right) print(root.data, end=' ')

Driver code

arr = [40, 30, 35, 80, 100] root = preToBST(arr) postorder(root)

C#

using System; using System.Collections.Generic;

// Class definition for a tree node public class Node { public int data; public Node left; public Node right; public Node(int val) { data = val; left = null; right = null; } }

public class GfG { public static Node preToBST(int[] pre) { int n = pre.Length;

  // Stack to keep track of ancestors
  Stack<Node> st = new Stack<Node>();

  // First element is root
  Node root = new Node(pre[0]);
  st.Push(root);

  // Process remaining elements
  for (int i = 1; i < n; i++)
  {
      // To store last popped node
      Node temp = null;

      // Find correct parent by popping smaller elements
      while (st.Count > 0 && pre[i] > st.Peek().data)
      {
          temp = st.Pop();
      }

      // If popped, attach as right child
      if (temp!= null)
      {
          temp.right = new Node(pre[i]);
          st.Push(temp.right);
      }
      else
      {
          // Else attach as left child
          st.Peek().left = new Node(pre[i]);
          st.Push(st.Peek().left);
      }
  }

  return root;

}

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

// Driver code public static void Main(string[] args) { int[] arr = {40, 30, 35, 80, 100};

  Node root = preToBST(arr);

  postorder(root);

} }

JavaScript

// Class definition for a tree node class Node { constructor(val) { this.data = val; this.left = null; this.right = null; } }

function preToBST(pre) { let n = pre.length;

// Stack to keep track of ancestors let st = [];

// First element is root let root = new Node(pre[0]); st.push(root);

// Process remaining elements for (let i = 1; i < n; i++) {

// To store last popped node
let temp = null;

// Find correct parent by popping smaller elements
while (st.length > 0 && pre[i] > st[st.length - 1].data) {
  temp = st.pop();
}

// If popped, attach as right child
if (temp!== null) {
  temp.right = new Node(pre[i]);
  st.push(temp.right);
} else {
    
  // Else attach as left child
  st[st.length - 1].left = new Node(pre[i]);
  st.push(st[st.length - 1].left);
}

}

return root; }

function postorder(root) { if (!root) return; postorder(root.left); postorder(root.right); console.log(root.data + " "); }

// Driver code let arr = [40, 30, 35, 80, 100];

let root = preToBST(arr);

postorder(root);

`

**Time Complexity: O(n)
**Space Complexity: O(h)