Construct BST from Preorder Traversal

Last Updated : 22 Oct, 2026

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

Examples:

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

blobid0_1777091399


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

Input: pre[] = [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

Try It Yourself
redirect icon

[Naive Approach] 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<int> &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<int> 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);
}

Output
35 30 100 80 40 

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

The first element of preorder traversal is always the root.

  • First construct root using first element.
  • 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<int> &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<int> &pre)
{

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

// Driver code
int main() {
    vector<int> 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);

Output
35 30 100 80 40 

[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. 

  • Initialize range as [-inf, +inf].
  • Begin with the first element of the preorder traversal, create a node with the given key.
  • Set the range as [-inf, key] for left subtree and [key, inf] for right subtree.
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<int> &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<int> &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<int> 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);

Output
35 30 100 80 40 

[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.
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<int> &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<int> 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 collections import deque

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


def preToBST(pre):
    if not pre:
        return None

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

    for i in range(1, len(pre)):
        temp = None

        while stack and pre[i] > stack[-1].data:
            temp = stack.pop()

        if temp is not None:
            temp.right = Node(pre[i])
            stack.append(temp.right)
        else:
            stack[-1].left = Node(pre[i])
            stack.append(stack[-1].left)

    return root


# Driver code
def printLevelOrder(root):
    if not root:
        print("Empty")
        return

    queue = deque([root])
    result = []

    while queue:
        node = queue.popleft()

        if node:
            result.append(str(node.data))
            queue.append(node.left)
            queue.append(node.right)
        else:
            result.append("N")

    while result and result[-1] == "N":
        result.pop()

    print(" ".join(result))


if __name__ == "__main__":
    pre = [12, 6, 17, 16]
    root = preToBST(pre)
    printLevelOrder(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);

Output
35 30 100 80 40 
Comment