Construct BST from given preorder traversal | Set 1
Last Updated :
14 Dec, 2023
Given the preorder traversal of a binary search tree, construct the BST.
Examples:
Input: {10, 5, 1, 7, 40, 50}
Output: 10
/ \
5 40
/ \ \
1 7 50
Naive approach: To solve the problem follow the below idea:
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 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.:
10
/ \
{5, 1, 7} {40, 50}
We recursively follow the above steps for subarrays {5, 1, 7} and {40, 50}, and get the complete tree.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class node {
public :
int data;
node* left;
node* right;
};
node* newNode( int data)
{
node* temp = new node();
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
node* constructTreeUtil( int pre[], int * preIndex, int low,
int high, int size)
{
if (*preIndex >= size || low > high)
return NULL;
node* root = newNode(pre[*preIndex]);
*preIndex = *preIndex + 1;
if (low == high)
return root;
int i;
for (i = low; i <= high; ++i)
if (pre[i] > root->data)
break ;
root->left = constructTreeUtil(pre, preIndex, *preIndex,
i - 1, size);
root->right
= constructTreeUtil(pre, preIndex, i, high, size);
return root;
}
node* constructTree( int pre[], int size)
{
int preIndex = 0;
return constructTreeUtil(pre, &preIndex, 0, size - 1,
size);
}
void printInorder(node* node)
{
if (node == NULL)
return ;
printInorder(node->left);
cout << node->data << " " ;
printInorder(node->right);
}
int main()
{
int pre[] = { 10, 5, 1, 7, 40, 50 };
int size = sizeof (pre) / sizeof (pre[0]);
node* root = constructTree(pre, size);
printInorder(root);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* left;
struct node* right;
};
struct node* newNode( int data)
{
struct node* temp
= ( struct node*) malloc ( sizeof ( struct node));
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
struct node* constructTreeUtil( int pre[], int * preIndex,
int low, int high, int size)
{
if (*preIndex >= size || low > high)
return NULL;
struct node* root = newNode(pre[*preIndex]);
*preIndex = *preIndex + 1;
if (low == high)
return root;
int i;
for (i = low; i <= high; ++i)
if (pre[i] > root->data)
break ;
root->left = constructTreeUtil(pre, preIndex, *preIndex,
i - 1, size);
root->right
= constructTreeUtil(pre, preIndex, i, high, size);
return root;
}
struct node* constructTree( int pre[], int size)
{
int preIndex = 0;
return constructTreeUtil(pre, &preIndex, 0, size - 1,
size);
}
void printInorder( struct node* node)
{
if (node == NULL)
return ;
printInorder(node->left);
printf ( "%d " , node->data);
printInorder(node->right);
}
int main()
{
int pre[] = { 10, 5, 1, 7, 40, 50 };
int size = sizeof (pre) / sizeof (pre[0]);
struct node* root = constructTree(pre, size);
printInorder(root);
return 0;
}
|
Java
class Node {
int data;
Node left, right;
Node( int d)
{
data = d;
left = right = null ;
}
}
class Index {
int index = 0 ;
}
class BinaryTree {
Index index = new Index();
Node constructTreeUtil( int pre[], Index preIndex,
int low, int high, int size)
{
if (preIndex.index >= size || low > high) {
return null ;
}
Node root = new Node(pre[preIndex.index]);
preIndex.index = preIndex.index + 1 ;
if (low == high) {
return root;
}
int i;
for (i = low; i <= high; ++i) {
if (pre[i] > root.data) {
break ;
}
}
root.left = constructTreeUtil(
pre, preIndex, preIndex.index, i - 1 , size);
root.right = constructTreeUtil(pre, preIndex, i,
high, size);
return root;
}
Node constructTree( int pre[], int size)
{
return constructTreeUtil(pre, index, 0 , size - 1 ,
size);
}
void printInorder(Node node)
{
if (node == null ) {
return ;
}
printInorder(node.left);
System.out.print(node.data + " " );
printInorder(node.right);
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
int pre[] = new int [] { 10 , 5 , 1 , 7 , 40 , 50 };
int size = pre.length;
Node root = tree.constructTree(pre, size);
tree.printInorder(root);
}
}
|
Python3
class Node():
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def getPreIndex():
return constructTreeUtil.preIndex
def incrementPreIndex():
constructTreeUtil.preIndex + = 1
def constructTreeUtil(pre, low, high):
if (low > high):
return None
root = Node(pre[getPreIndex()])
incrementPreIndex()
if low = = high:
return root
r_root = - 1
for i in range (low, high + 1 ):
if (pre[i] > root.data):
r_root = i
break
if r_root = = - 1 :
r_root = getPreIndex() + (high - low)
root.left = constructTreeUtil(pre, getPreIndex(), r_root - 1 )
root.right = constructTreeUtil(pre, r_root, high)
return root
def constructTree(pre):
size = len (pre)
constructTreeUtil.preIndex = 0
return constructTreeUtil(pre, 0 , size - 1 )
def printInorder(root):
if root is None :
return
printInorder(root.left)
print (root.data, end = ' ' )
printInorder(root.right)
if __name__ = = '__main__' :
pre = [ 10 , 5 , 1 , 7 , 40 , 50 ]
root = constructTree(pre)
printInorder(root)
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int d)
{
data = d;
left = right = null ;
}
}
public class Index {
public int index = 0;
}
public class BinaryTree {
public Index index = new Index();
public virtual Node constructTreeUtil( int [] pre,
Index preIndex,
int low, int high,
int size)
{
if (preIndex.index >= size || low > high) {
return null ;
}
Node root = new Node(pre[preIndex.index]);
preIndex.index = preIndex.index + 1;
if (low == high) {
return root;
}
int i;
for (i = low; i <= high; ++i) {
if (pre[i] > root.data) {
break ;
}
}
root.left = constructTreeUtil(
pre, preIndex, preIndex.index, i - 1, size);
root.right = constructTreeUtil(pre, preIndex, i,
high, size);
return root;
}
public virtual Node constructTree( int [] pre, int size)
{
return constructTreeUtil(pre, index, 0, size - 1,
size);
}
public virtual void printInorder(Node node)
{
if (node == null ) {
return ;
}
printInorder(node.left);
Console.Write(node.data + " " );
printInorder(node.right);
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
int [] pre = new int [] { 10, 5, 1, 7, 40, 50 };
int size = pre.Length;
Node root = tree.constructTree(pre, size);
tree.printInorder(root);
}
}
|
Javascript
<script>
class Node{
constructor(data){
this .data = data
this .left = null
this .right = null
}
}
function getPreIndex(){
return constructTreeUtil.preIndex
}
function incrementPreIndex(){
constructTreeUtil.preIndex += 1
}
function constructTreeUtil(pre, low, high){
if (low > high)
return null
let root = new Node(pre[getPreIndex()])
incrementPreIndex()
if (low == high)
return root
let r_root = -1
for (let i=low;i<high+1;i++){
if (pre[i] > root.data){
r_root = i
break
}
}
if (r_root == -1)
r_root = getPreIndex() + (high - low)
root.left = constructTreeUtil(pre, getPreIndex(), r_root-1)
root.right = constructTreeUtil(pre, r_root, high)
return root
}
function constructTree(pre){
let size = pre.length
constructTreeUtil.preIndex = 0
return constructTreeUtil(pre, 0, size-1)
}
function printInorder(root){
if (root == null )
return
printInorder(root.left)
document.write(root.data, ' ' )
printInorder(root.right)
}
let pre = [10, 5, 1, 7, 40, 50]
let root = constructTree(pre)
printInorder(root)
</script>
|
Output
Inorder traversal of the constructed tree:
1 5 7 10 40 50
Time Complexity: O(N2)
Auxiliary Space: O(N)
Approach: To solve the problem follow the below idea:
Using the recursion concept and iterating through the array of the given elements we can generate the BST
Follow the below steps to solve the problem:
- Create a new Node for every value in the array
- Create a BST using these new Nodes and insert them according to the rules of the BST
- Print the inorder of the BST
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Node {
public :
int data;
Node* left;
Node* right;
Node( int data)
{
this ->data = data;
this ->left = this ->right = NULL;
}
};
static Node* node;
Node* createNode(Node* node, int data)
{
if (node == NULL)
node = new Node(data);
if (node->data > data)
node->left = createNode(node->left, data);
if (node->data < data)
node->right = createNode(node->right, data);
return node;
}
void create( int data) { node = createNode(node, data); }
void inorderRec(Node* root)
{
if (root != NULL) {
inorderRec(root->left);
cout << root->data << " " ;
inorderRec(root->right);
}
}
int main()
{
vector< int > nodeData = { 10, 5, 1, 7, 40, 50 };
for ( int i = 0; i < nodeData.size(); i++) {
create(nodeData[i]);
}
inorderRec(node);
}
|
Java
class Node {
int data;
Node left, right;
Node( int data)
{
this .data = data;
this .left = this .right = null ;
}
}
class CreateBSTFromPreorder {
private static Node node;
public static Node createNode(Node node, int data)
{
if (node == null )
node = new Node(data);
if (node.data > data)
node.left = createNode(node.left, data);
if (node.data < data)
node.right = createNode(node.right, data);
return node;
}
public static void create( int data)
{
node = createNode(node, data);
}
public static void inorderRec(Node root)
{
if (root != null ) {
inorderRec(root.left);
System.out.print(root.data);
System.out.print( " " );
inorderRec(root.right);
}
}
public static void main(String[] args)
{
int [] nodeData = { 10 , 5 , 1 , 7 , 40 , 50 };
for ( int i = 0 ; i < nodeData.length; i++) {
create(nodeData[i]);
}
inorderRec(node);
}
}
|
Python3
class Node:
data = 0
left = None
right = None
def __init__( self , data):
self .data = data
self .left = None
self .right = None
class CreateBSTFromPreorder:
node = None
@staticmethod
def createNode(node, data):
if (node = = None ):
node = Node(data)
if (node.data > data):
node.left = CreateBSTFromPreorder.createNode(node.left, data)
if (node.data < data):
node.right = CreateBSTFromPreorder.createNode(node.right, data)
return node
@staticmethod
def create(data):
CreateBSTFromPreorder.node = CreateBSTFromPreorder.createNode(
CreateBSTFromPreorder.node, data)
@staticmethod
def inorderRec(root):
if (root ! = None ):
CreateBSTFromPreorder.inorderRec(root.left)
print (root.data)
CreateBSTFromPreorder.inorderRec(root.right)
@staticmethod
def main(args):
nodeData = [ 10 , 5 , 1 , 7 , 40 , 50 ]
i = 0
while (i < len (nodeData)):
CreateBSTFromPreorder.create(nodeData[i])
i + = 1
CreateBSTFromPreorder.inorderRec(CreateBSTFromPreorder.node)
if __name__ = = "__main__" :
CreateBSTFromPreorder.main([])
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
this .left = this .right = null ;
}
}
public class CreateBSTFromPreorder {
private static Node node;
public static Node createNode(Node node, int data)
{
if (node == null )
node = new Node(data);
if (node.data > data)
node.left = createNode(node.left, data);
if (node.data < data)
node.right = createNode(node.right, data);
return node;
}
public static void create( int data)
{
node = createNode(node, data);
}
public static void inorderRec(Node root)
{
if (root != null ) {
inorderRec(root.left);
Console.Write(root.data);
Console.Write( " " );
inorderRec(root.right);
}
}
public static void Main(String[] args)
{
int [] nodeData = { 10, 5, 1, 7, 40, 50 };
for ( int i = 0; i < nodeData.Length; i++) {
create(nodeData[i]);
}
inorderRec(node);
}
}
|
Javascript
<script>
class Node {
constructor(data) {
this .data = data;
this .left = this .right = null ;
}
}
var node;
function createNode(node , data) {
if (node == null )
node = new Node(data);
if (node.data > data)
node.left = createNode(node.left, data);
if (node.data < data)
node.right = createNode(node.right, data);
return node;
}
function create(data) {
node = createNode(node, data);
}
function inorderRec(root) {
if (root != null ) {
inorderRec(root.left);
document.write(root.data+ "<br/>" );
inorderRec(root.right);
}
}
var nodeData = [ 10, 5, 1, 7, 40, 50 ];
for (i = 0; i < nodeData.length; i++)
{
create(nodeData[i]);
}
inorderRec(node);
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: To solve the problem follow the below idea:
The trick is to set a range {min .. max} for every node.
Follow the below steps to solve the problem:
- Initialize the range as {INT_MIN .. INT_MAX}
- The first node will definitely be in range, so create a root node.
- To construct the left subtree, set the range as {INT_MIN …root->data}.
- If a value is in the range {INT_MIN .. root->data}, the values are part of the left subtree.
- To construct the right subtree, set the range as {root->data..max .. INT_MAX}.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class node {
public :
int data;
node* left;
node* right;
};
node* newNode( int data)
{
node* temp = new node();
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
node* constructTreeUtil( int pre[], int * preIndex, int key,
int min, int max, int size)
{
if (*preIndex >= size)
return NULL;
node* root = NULL;
if (key > min && key < max) {
root = newNode(key);
*preIndex = *preIndex + 1;
if (*preIndex < size) {
root->left = constructTreeUtil(pre, preIndex,
pre[*preIndex],
min, key, size);
}
if (*preIndex < size) {
root->right = constructTreeUtil(pre, preIndex,
pre[*preIndex],
key, max, size);
}
}
return root;
}
node* constructTree( int pre[], int size)
{
int preIndex = 0;
return constructTreeUtil(pre, &preIndex, pre[0],
INT_MIN, INT_MAX, size);
}
void printInorder(node* node)
{
if (node == NULL)
return ;
printInorder(node->left);
cout << node->data << " " ;
printInorder(node->right);
}
int main()
{
int pre[] = { 10, 5, 1, 7, 40, 50 };
int size = sizeof (pre) / sizeof (pre[0]);
node* root = constructTree(pre, size);
printInorder(root);
return 0;
}
|
C
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* left;
struct node* right;
};
struct node* newNode( int data)
{
struct node* temp
= ( struct node*) malloc ( sizeof ( struct node));
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
struct node* constructTreeUtil( int pre[], int * preIndex,
int key, int min, int max,
int size)
{
if (*preIndex >= size)
return NULL;
struct node* root = NULL;
if (key > min && key < max) {
root = newNode(key);
*preIndex = *preIndex + 1;
if (*preIndex < size) {
root->left = constructTreeUtil(pre, preIndex,
pre[*preIndex],
min, key, size);
}
if (*preIndex < size) {
root->right = constructTreeUtil(pre, preIndex,
pre[*preIndex],
key, max, size);
}
}
return root;
}
struct node* constructTree( int pre[], int size)
{
int preIndex = 0;
return constructTreeUtil(pre, &preIndex, pre[0],
INT_MIN, INT_MAX, size);
}
void printInorder( struct node* node)
{
if (node == NULL)
return ;
printInorder(node->left);
printf ( "%d " , node->data);
printInorder(node->right);
}
int main()
{
int pre[] = { 10, 5, 1, 7, 40, 50 };
int size = sizeof (pre) / sizeof (pre[0]);
struct node* root = constructTree(pre, size);
printInorder(root);
return 0;
}
|
Java
class Node {
int data;
Node left, right;
Node( int d)
{
data = d;
left = right = null ;
}
}
class Index {
int index = 0 ;
}
class BinaryTree {
Index index = new Index();
Node constructTreeUtil( int pre[], Index preIndex,
int key, int min, int max,
int size)
{
if (preIndex.index >= size) {
return null ;
}
Node root = null ;
if (key > min && key < max) {
root = new Node(key);
preIndex.index = preIndex.index + 1 ;
if (preIndex.index < size) {
root.left = constructTreeUtil(
pre, preIndex, pre[preIndex.index], min,
key, size);
}
if (preIndex.index < size) {
root.right = constructTreeUtil(
pre, preIndex, pre[preIndex.index], key,
max, size);
}
}
return root;
}
Node constructTree( int pre[], int size)
{
int preIndex = 0 ;
return constructTreeUtil(pre, index, pre[ 0 ],
Integer.MIN_VALUE,
Integer.MAX_VALUE, size);
}
void printInorder(Node node)
{
if (node == null ) {
return ;
}
printInorder(node.left);
System.out.print(node.data + " " );
printInorder(node.right);
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
int pre[] = new int [] { 10 , 5 , 1 , 7 , 40 , 50 };
int size = pre.length;
Node root = tree.constructTree(pre, size);
tree.printInorder(root);
}
}
|
Python3
INT_MIN = - float ( "inf" )
INT_MAX = float ( "inf" )
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def getPreIndex():
return constructTreeUtil.preIndex
def incrementPreIndex():
constructTreeUtil.preIndex + = 1
def constructTreeUtil(pre, key, mini, maxi, size):
if (getPreIndex() > = size):
return None
root = None
if (key > mini and key < maxi):
root = Node(key)
incrementPreIndex()
if (getPreIndex() < size):
root.left = constructTreeUtil(pre,
pre[getPreIndex()],
mini, key, size)
if (getPreIndex() < size):
root.right = constructTreeUtil(pre,
pre[getPreIndex()],
key, maxi, size)
return root
def constructTree(pre):
constructTreeUtil.preIndex = 0
size = len (pre)
return constructTreeUtil(pre, pre[ 0 ], INT_MIN, INT_MAX, size)
def printInorder(node):
if node is None :
return
printInorder(node.left)
print (node.data, end = " " )
printInorder(node.right)
pre = [ 10 , 5 , 1 , 7 , 40 , 50 ]
root = constructTree(pre)
printInorder(root)
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int d)
{
data = d;
left = right = null ;
}
}
public class Index {
public int index = 0;
}
public class BinaryTree {
public Index index = new Index();
public virtual Node constructTreeUtil( int [] pre,
Index preIndex,
int key, int min,
int max, int size)
{
if (preIndex.index >= size) {
return null ;
}
Node root = null ;
if (key > min && key < max) {
root = new Node(key);
preIndex.index = preIndex.index + 1;
if (preIndex.index < size) {
root.left = constructTreeUtil(
pre, preIndex, pre[preIndex.index], min,
key, size);
}
if (preIndex.index < size) {
root.right = constructTreeUtil(
pre, preIndex, pre[preIndex.index], key,
max, size);
}
}
return root;
}
public virtual Node constructTree( int [] pre, int size)
{
return constructTreeUtil(pre, index, pre[0],
int .MinValue, int .MaxValue,
size);
}
public virtual void printInorder(Node node)
{
if (node == null ) {
return ;
}
printInorder(node.left);
Console.Write(node.data + " " );
printInorder(node.right);
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
int [] pre = new int [] { 10, 5, 1, 7, 40, 50 };
int size = pre.Length;
Node root = tree.constructTree(pre, size);
tree.printInorder(root);
}
}
|
Javascript
<script>
class Node {
constructor(d) {
this .data = d;
this .left = this .right = null ;
}
}
class Index {
constructor(){
this .index = 0;
}
}
index = new Index();
function constructTreeUtil(pre, preIndex , key , min , max , size) {
if (preIndex.index >= size) {
return null ;
}
var root = null ;
if (key > min && key < max) {
root = new Node(key);
preIndex.index = preIndex.index + 1;
if (preIndex.index < size) {
root.left = constructTreeUtil(pre, preIndex,
pre[preIndex.index], min, key, size);
}
if (preIndex.index < size)
{
root.right = constructTreeUtil(pre, preIndex,
pre[preIndex.index], key, max, size);
}
}
return root;
}
function constructTree(pre , size) {
var preIndex = 0;
return constructTreeUtil(pre, index, pre[0],
Number.MIN_VALUE, Number.MAX_VALUE, size);
}
function printInorder(node) {
if (node == null ) {
return ;
}
printInorder(node.left);
document.write(node.data + " " );
printInorder(node.right);
}
var pre =[ 10, 5, 1, 7, 40, 50 ];
var size = pre.length;
var root = constructTree(pre, size);
document.write( "Inorder traversal of the constructed tree is <br/>" );
printInorder(root);
</script>
|
Output
Inorder traversal of the constructed tree:
1 5 7 10 40 50
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...