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]
**Output: [35, 30, 100, 80, 40]
**Explanation: PreOrder: 40 30 35 80 100**Input: [10, 5, 1, 7, 40, 50]
**Output:
**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
- [Better Approach] Using Find First Greater than Root - O(n²) Time O(h) Space
- [Efficient Approach 1] Pass Range in Recursion - O(n) Time O(h) Space
- [Expected Approach - 2] Using Stack - O(n) Time O(h) Space
[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 rootdef preToBST(pre): root = None
for x in pre:
root = insertBST(root, x)
return rootdef 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.:
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 rootdef 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:
- Initialize the range as {-inf , +inf}
- The first node will definitely be in range, so create a root node.
- To construct the left subtree, set the range as {-inf, root.key} and for right subtree as [root.key, +inf]
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 rootFunction 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:
- If the current value is less than the top of stack, it means it belongs to the left subtree, so we attach it as the left child of the stack’s top node.
- If the current value is greater than the top of stack, we keep popping from the stack until we find a node smaller than the current value. The last popped node becomes the parent, and we attach the current node as its right child.
- We push the current element into the stack.
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)


