Given a distinct sequence of keys which represents preorder traversal of a binary search tree (BST), construct the tree from the postorder sequence.





For example, below BST should be constructed for preorder traversal { 15, 10, 8, 12, 20, 16, 25 }



For a given preorder sequence, we can easily build a BST by recursively repeating the following steps for all keys in it.

Construct the root node of BST which would be the first key in the preorder sequence.

Find index i of the first key in the preorder sequence which is greater than the root node.

Recur for the left sub-tree with keys in the preorder sequence that appears before the i’th index (excluding first index).

Recur for the right sub-tree with keys in the preorder sequence that appears after the i’th index (including i’th index).



To make context more clear, let’s consider the preorder traversal {15, 10, 8, 12, 20, 16, 25}

The first item in the preorder sequence 15 becomes the root node.

Since 20 is the first key in the preorder sequence which greater than the root node, left sub-tree consists of keys {10, 8, 12} and right sub-tree consists of keys {20, 16, 25} .

To construct the complete BST, recursively repeat the above steps for preorder sequence {10, 8, 12} and {20, 16, 25} .



This is demonstrated below in C, Java and Python –

C #include <stdio.h> #include <stdlib.h> // Data structure to store a Binary Tree node struct Node { int key; struct Node *left, *right; }; // Function to create a new binary tree node having given key struct Node* newNode(int key) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->key = key; node->left = node->right = NULL; return node; } // Recursive function to perform inorder traversal of a binary tree void inorder(struct Node* root) { if (root == NULL) return; inorder(root->left); printf("%d ", root->key); inorder(root->right); } // Recursive function to build a BST from a preorder sequence struct Node* constructBST(int preorder[], int start, int end) { // base case if (start > end) return NULL; // Construct the root node of the sub-tree formed by keys of the // preorder sequence in range [start, end] struct Node *node = newNode(preorder[start]); // search the index of first element in current range of preorder // sequence which is larger than the value of root node int i; for (i = start; i <= end; i++) { if (preorder[i] > node->key) break; } // recursively construct the left sub-tree node->left = constructBST(preorder, start + 1, i - 1); // recursively construct the right sub-tree node->right = constructBST(preorder, i, end); // return current node return node; } int main(void) { /* Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 */ int preorder[] = { 15, 10, 8, 12, 20, 16, 25 }; int n = sizeof(preorder)/sizeof(preorder[0]); // construct the BST struct Node* root = constructBST(preorder, 0, n - 1); // print the BST printf("Inorder Traversal of BST is : "); // inorder on the BST always returns a sorted sequence inorder(root); return 0; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 #include <stdio.h> #include <stdlib.h> // Data structure to store a Binary Tree node struct Node { int key ; struct Node * left , * right ; } ; // Function to create a new binary tree node having given key struct Node * newNode ( int key ) { struct Node * node = ( struct Node * ) malloc ( sizeof ( struct Node ) ) ; node -> key = key ; node -> left = node -> right = NULL ; return node ; } // Recursive function to perform inorder traversal of a binary tree void inorder ( struct Node * root ) { if ( root == NULL ) return ; inorder ( root -> left ) ; printf ( "%d " , root -> key ) ; inorder ( root -> right ) ; } // Recursive function to build a BST from a preorder sequence struct Node * constructBST ( int preorder [ ] , int start , int end ) { // base case if ( start > end ) return NULL ; // Construct the root node of the sub-tree formed by keys of the // preorder sequence in range [start, end] struct Node * node = newNode ( preorder [ start ] ) ; // search the index of first element in current range of preorder // sequence which is larger than the value of root node int i ; for ( i = start ; i <= end ; i ++ ) { if ( preorder [ i ] > node -> key ) break ; } // recursively construct the left sub-tree node -> left = constructBST ( preorder , start + 1 , i - 1 ) ; // recursively construct the right sub-tree node -> right = constructBST ( preorder , i , end ) ; // return current node return node ; } int main ( void ) { /* Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 */ int preorder [ ] = { 15 , 10 , 8 , 12 , 20 , 16 , 25 } ; int n = sizeof ( preorder ) / sizeof ( preorder [ 0 ] ) ; // construct the BST struct Node * root = constructBST ( preorder , 0 , n - 1 ) ; // print the BST printf ( "Inorder Traversal of BST is : " ) ; // inorder on the BST always returns a sorted sequence inorder ( root ) ; return 0 ; } Download Run Code Output:



Inorder Traversal of BST is : 8 10 12 15 16 20 25

Java // Class to store a Binary Tree node class Node { int key; Node left, right; Node(int key) { this.key = key; } } class Main { // Recursive function to perform inorder traversal of a binary tree public static void inorder(Node root) { if (root == null) { return; } inorder(root.left); System.out.print(root.key + " "); inorder(root.right); } // Recursive function to build a BST from a preorder sequence public static Node constructBST(int[] preorder, int start, int end) { // base case if (start > end) { return null; } // Construct the root node of the sub-tree formed by keys of the // preorder sequence in range [start, end] Node node = new Node(preorder[start]); // search the index of first element in current range of preorder // sequence which is larger than the value of root node int i; for (i = start; i <= end; i++) { if (preorder[i] > node.key) { break; } } // recursively construct the left sub-tree node.left = constructBST(preorder, start + 1, i - 1); // recursively construct the right sub-tree node.right = constructBST(preorder, i, end); // return current node return node; } public static void main(String[] args) { /* Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 */ int[] preorder = { 15, 10, 8, 12, 20, 16, 25 }; // construct the BST Node root = constructBST(preorder, 0, preorder.length - 1); // print the BST System.out.print("Inorder Traversal of BST is : "); // inorder on the BST always returns a sorted sequence inorder(root); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 // Class to store a Binary Tree node class Node { int key ; Node left , right ; Node ( int key ) { this . key = key ; } } class Main { // Recursive function to perform inorder traversal of a binary tree public static void inorder ( Node root ) { if ( root == null ) { return ; } inorder ( root . left ) ; System . out . print ( root . key + " " ) ; inorder ( root . right ) ; } // Recursive function to build a BST from a preorder sequence public static Node constructBST ( int [ ] preorder , int start , int end ) { // base case if ( start > end ) { return null ; } // Construct the root node of the sub-tree formed by keys of the // preorder sequence in range [start, end] Node node = new Node ( preorder [ start ] ) ; // search the index of first element in current range of preorder // sequence which is larger than the value of root node int i ; for ( i = start ; i <= end ; i ++ ) { if ( preorder [ i ] > node . key ) { break ; } } // recursively construct the left sub-tree node . left = constructBST ( preorder , start + 1 , i - 1 ) ; // recursively construct the right sub-tree node . right = constructBST ( preorder , i , end ) ; // return current node return node ; } public static void main ( String [ ] args ) { /* Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 */ int [ ] preorder = { 15 , 10 , 8 , 12 , 20 , 16 , 25 } ; // construct the BST Node root = constructBST ( preorder , 0 , preorder . length - 1 ) ; // print the BST System . out . print ( "Inorder Traversal of BST is : " ) ; // inorder on the BST always returns a sorted sequence inorder ( root ) ; } } Download Run Code Output:



Inorder Traversal of BST is : 8 10 12 15 16 20 25

Python # Class to store a Binary Tree node class Node: def __init__(self, key): self.key = key # Recursive function to perform inorder traversal of a binary tree def inorder(root): if root is None: return inorder(root.left) print(root.key, end=' ') inorder(root.right) # Recursive function to build a BST from a preorder sequence def constructBST(preorder, start, end): # base case if start > end: return None # Construct the root node of the sub-tree formed by keys of the # preorder sequence in range [start, end] node = Node(preorder[start]) # search the index of first element in current range of preorder # sequence which is larger than the value of root node i = start while i <= end: if preorder[i] > node.key: break i = i + 1 # recursively construct the left sub-tree node.left = constructBST(preorder, start + 1, i - 1) # recursively construct the right sub-tree node.right = constructBST(preorder, i, end) # return current node return node if __name__ == '__main__': """ Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 """ preorder = [15, 10, 8, 12, 20, 16, 25] # construct the BST root = constructBST(preorder, 0, len(preorder) - 1) # print the BST print("Inorder Traversal of BST is: ", end='') # inorder on the BST always returns a sorted sequence inorder(root) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 # Class to store a Binary Tree node class Node : def __init__ ( self , key ) : self . key = key # Recursive function to perform inorder traversal of a binary tree def inorder ( root ) : if root is None : return inorder ( root . left ) print ( root . key , end = ' ' ) inorder ( root . right ) # Recursive function to build a BST from a preorder sequence def constructBST ( preorder , start , end ) : # base case if start > end : return None # Construct the root node of the sub-tree formed by keys of the # preorder sequence in range [start, end] node = Node ( preorder [ start ] ) # search the index of first element in current range of preorder # sequence which is larger than the value of root node i = start while i <= end : if preorder [ i ] > node . key : break i = i + 1 # recursively construct the left sub-tree node . left = constructBST ( preorder , start + 1 , i - 1 ) # recursively construct the right sub-tree node . right = constructBST ( preorder , i , end ) # return current node return node if __name__ == '__main__' : """ Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 """ preorder = [ 15 , 10 , 8 , 12 , 20 , 16 , 25 ] # construct the BST root = constructBST ( preorder , 0 , len ( preorder ) - 1 ) # print the BST print ( "Inorder Traversal of BST is: " , end = '' ) # inorder on the BST always returns a sorted sequence inorder ( root ) Download Run Code Output:



Inorder Traversal of BST is : 8 10 12 15 16 20 25







The time complexity of above solution is O(n2) and takes O(n) extra space for the call stack. We can reduce the time complexity to O(n) by following a different approach that doesn’t involve searching for index which separates the keys of left and right sub-tree in preorder sequence.

We know that in a BST, each node has key which is greater than all keys present in its left sub-tree, and less than the keys present in the right sub-tree. The idea to pass the information regarding the valid range of keys for current root node and its children in the recursion itself.

We start by setting the range as [INT_MIN, INT_MAX] for the root node. This means that the root node and any of its children can have keys in the ranging between INT_MIN and INT_MAX . Like previous approach, we construct the root node of BST from the first item in the preorder sequence. Suppose the root node has value x, we recur for right sub-tree with range (x, INT_MAX) and recur for left sub-tree with range [INT_MIN, x) . To construct the complete BST, we recursively set the range for each recursive call and simply return if next element of preorder traversal is out of the valid range.

Here’s C++, Java and Python program that demonstrates it:

C++ #include <iostream> #include <vector> #include <climits> using namespace std; // Data structure to store a Binary Tree node struct Node { int data; Node *left, *right; }; // Function to create a new binary tree node having given key Node* newNode(int key) { Node* node = new Node; node->data = key; node->left = node->right = nullptr; return node; } // Function to print the inorder traversal of a binary tree void inorder(Node* root) { if (root == nullptr) return; inorder(root->left); cout << root->data << ' '; inorder(root->right); } // Recursive function to build a BST from a preorder sequence Node* buildTree(vector<int> const &preorder, int& pIndex, int min, int max) { // Base case if (pIndex == preorder.size()) return nullptr; // Return if next element of preorder traversal is not in the valid range int val = preorder[pIndex]; if (val < min || val > max) return nullptr; // Construct the root node and increment pIndex Node* root = newNode(val); pIndex++; // Since all elements in the left sub-tree of a BST must be less // than the value of root node, set range as [min, val-1] and recur root->left = buildTree(preorder, pIndex, min, val-1); // Since all elements in the right sub-tree of a BST must be greater // than the value of root node, set range as [val+1..max] and recur root->right = buildTree(preorder, pIndex, val+1, max); return root; } // Build a BST from a preorder sequence Node* buildTree(vector<int> const &preorder) { // start from the root node (first element in preorder sequence) int pIndex = 0; // set range of the root node as [INT_MIN, INT_MAX] and recur return buildTree(preorder, pIndex, INT_MIN, INT_MAX); } int main() { /* Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 */ // preorder traversal of BST vector<int> preorder = { 15, 10, 8, 12, 20, 16, 25 }; // construct the BST Node* root = buildTree(preorder); // print the BST cout << "Inorder Traversal of BST is : "; // inorder on the BST always returns a sorted sequence inorder(root); return 0; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 #include <iostream> #include <vector> #include <climits> using namespace std ; // Data structure to store a Binary Tree node struct Node { int data ; Node * left , * right ; } ; // Function to create a new binary tree node having given key Node * newNode ( int key ) { Node * node = new Node ; node -> data = key ; node -> left = node -> right = nullptr ; return node ; } // Function to print the inorder traversal of a binary tree void inorder ( Node * root ) { if ( root == nullptr ) return ; inorder ( root -> left ) ; cout << root -> data << ' ' ; inorder ( root -> right ) ; } // Recursive function to build a BST from a preorder sequence Node * buildTree ( vector < int > const &preorder , int & pIndex , int min , int max ) { // Base case if ( pIndex == preorder . size ( ) ) return nullptr ; // Return if next element of preorder traversal is not in the valid range int val = preorder [ pIndex ] ; if ( val < min || val > max ) return nullptr ; // Construct the root node and increment pIndex Node * root = newNode ( val ) ; pIndex ++ ; // Since all elements in the left sub-tree of a BST must be less // than the value of root node, set range as [min, val-1] and recur root -> left = buildTree ( preorder , pIndex , min , val - 1 ) ; // Since all elements in the right sub-tree of a BST must be greater // than the value of root node, set range as [val+1..max] and recur root -> right = buildTree ( preorder , pIndex , val + 1 , max ) ; return root ; } // Build a BST from a preorder sequence Node * buildTree ( vector < int > const &preorder ) { // start from the root node (first element in preorder sequence) int pIndex = 0 ; // set range of the root node as [INT_MIN, INT_MAX] and recur return buildTree ( preorder , pIndex , INT_MIN , INT_MAX ) ; } int main ( ) { /* Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 */ // preorder traversal of BST vector < int > preorder = { 15 , 10 , 8 , 12 , 20 , 16 , 25 } ; // construct the BST Node * root = buildTree ( preorder ) ; // print the BST cout << "Inorder Traversal of BST is : " ; // inorder on the BST always returns a sorted sequence inorder ( root ) ; return 0 ; } Download Run Code Output:



Inorder Traversal of BST is : 8 10 12 15 16 20 25

Java import java.util.concurrent.atomic.AtomicInteger; // Class to store a Binary Tree node class Node { int data; Node left, right; Node(int data) { this.data = data; } } class Main { // Function to print the inorder traversal of a binary tree public static void inorder(Node root) { if (root == null) { return; } inorder(root.left); System.out.print(root.data + " "); inorder(root.right); } // Recursive function to build a BST from a preorder sequence public static Node buildTree(int[] preorder, AtomicInteger pIndex, int min, int max) { // Base case if (pIndex.get() == preorder.length) { return null; } // Return if next element of preorder traversal is not in the valid range int val = preorder[pIndex.get()]; if (val < min || val > max) { return null; } // Construct the root node and increment pIndex Node root = new Node(val); pIndex.incrementAndGet(); // Since all elements in the left sub-tree of a BST must be less // than the value of root node, set range as [min, val-1] and recur root.left = buildTree(preorder, pIndex, min, val-1); // Since all elements in the right sub-tree of a BST must be greater // than the value of root node, set range as [val+1..max] and recur root.right = buildTree(preorder, pIndex, val+1, max); return root; } // Build a BST from a preorder sequence public static Node buildTree(int[] preorder) { // start from the root node (first element in preorder sequence) // use AtomicInteger as Integer is passed by value in Java AtomicInteger pIndex = new AtomicInteger(0); // set range of the root node as [Integer.MIN_VALUE, Integer.MAX_VALUE] and recur return buildTree(preorder, pIndex, Integer.MIN_VALUE, Integer.MAX_VALUE); } public static void main(String[] args) { /* Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 */ // preorder traversal of BST int[] preorder = { 15, 10, 8, 12, 20, 16, 25 }; // construct the BST Node root = buildTree(preorder); // print the BST System.out.print("Inorder Traversal of BST is: "); // inorder on the BST always returns a sorted sequence inorder(root); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 import java . util . concurrent . atomic . AtomicInteger ; // Class to store a Binary Tree node class Node { int data ; Node left , right ; Node ( int data ) { this . data = data ; } } class Main { // Function to print the inorder traversal of a binary tree public static void inorder ( Node root ) { if ( root == null ) { return ; } inorder ( root . left ) ; System . out . print ( root . data + " " ) ; inorder ( root . right ) ; } // Recursive function to build a BST from a preorder sequence public static Node buildTree ( int [ ] preorder , AtomicInteger pIndex , int min , int max ) { // Base case if ( pIndex . get ( ) == preorder . length ) { return null ; } // Return if next element of preorder traversal is not in the valid range int val = preorder [ pIndex . get ( ) ] ; if ( val < min || val > max ) { return null ; } // Construct the root node and increment pIndex Node root = new Node ( val ) ; pIndex . incrementAndGet ( ) ; // Since all elements in the left sub-tree of a BST must be less // than the value of root node, set range as [min, val-1] and recur root . left = buildTree ( preorder , pIndex , min , val - 1 ) ; // Since all elements in the right sub-tree of a BST must be greater // than the value of root node, set range as [val+1..max] and recur root . right = buildTree ( preorder , pIndex , val + 1 , max ) ; return root ; } // Build a BST from a preorder sequence public static Node buildTree ( int [ ] preorder ) { // start from the root node (first element in preorder sequence) // use AtomicInteger as Integer is passed by value in Java AtomicInteger pIndex = new AtomicInteger ( 0 ) ; // set range of the root node as [Integer.MIN_VALUE, Integer.MAX_VALUE] and recur return buildTree ( preorder , pIndex , Integer . MIN_VALUE , Integer . MAX_VALUE ) ; } public static void main ( String [ ] args ) { /* Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 */ // preorder traversal of BST int [ ] preorder = { 15 , 10 , 8 , 12 , 20 , 16 , 25 } ; // construct the BST Node root = buildTree ( preorder ) ; // print the BST System . out . print ( "Inorder Traversal of BST is: " ) ; // inorder on the BST always returns a sorted sequence inorder ( root ) ; } } Download Run Code Output:



Inorder Traversal of BST is : 8 10 12 15 16 20 25

Python # Data structure to store a Binary Tree node class Node: def __init__(self, key, left=None, right=None): self.key = key self.left = left self.right = right # Function to print the inorder traversal of a binary tree def inorder(root): if root is None: return inorder(root.left) print(root.key, end=' ') inorder(root.right) # Recursive function to build a BST from a preorder sequence # start from the root node (first element in preorder sequence) # set range of the root node as [-INFINITY, INFINITY] def buildBST(preorder, pIndex=0, min=float('-inf'), max=float('inf')): # Base case if pIndex == len(preorder): return None, pIndex # Return if next element of preorder traversal is not in the valid range val = preorder[pIndex] if val < min or val > max: return None, pIndex # Construct the root node and increment pIndex root = Node(val) pIndex = pIndex + 1 # Since all elements in the left sub-tree of a BST must be less # than the value of root node, set range as [min, val-1] and recur root.left, pIndex = buildBST(preorder, pIndex, min, val-1) # Since all elements in the right sub-tree of a BST must be greater # than the value of root node, set range as [val+1..max] and recur root.right, pIndex = buildBST(preorder, pIndex, val+1, max) return root, pIndex if __name__ == '__main__': """ Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 """ # preorder traversal of BST preorder = [15, 10, 8, 12, 20, 16, 25] # construct the BST root = buildBST(preorder)[0] # print the BST print("Inorder Traversal of BST is:", end=' ') # inorder on the BST always returns a sorted sequence inorder(root) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 # Data structure to store a Binary Tree node class Node : def __init__ ( self , key , left = None , right = None ) : self . key = key self . left = left self . right = right # Function to print the inorder traversal of a binary tree def inorder ( root ) : if root is None : return inorder ( root . left ) print ( root . key , end = ' ' ) inorder ( root . right ) # Recursive function to build a BST from a preorder sequence # start from the root node (first element in preorder sequence) # set range of the root node as [-INFINITY, INFINITY] def buildBST ( preorder , pIndex = 0 , min = float ( '-inf' ) , max = float ( 'inf' ) ) : # Base case if pIndex == len ( preorder ) : return None , pIndex # Return if next element of preorder traversal is not in the valid range val = preorder [ pIndex ] if val < min or val > max : return None , pIndex # Construct the root node and increment pIndex root = Node ( val ) pIndex = pIndex + 1 # Since all elements in the left sub-tree of a BST must be less # than the value of root node, set range as [min, val-1] and recur root . left , pIndex = buildBST ( preorder , pIndex , min , val - 1 ) # Since all elements in the right sub-tree of a BST must be greater # than the value of root node, set range as [val+1..max] and recur root . right , pIndex = buildBST ( preorder , pIndex , val + 1 , max ) return root , pIndex if __name__ == '__main__' : """ Construct below BST 15 / \ / \ 10 20 / \ / \ / \ / \ 8 12 16 25 """ # preorder traversal of BST preorder = [ 15 , 10 , 8 , 12 , 20 , 16 , 25 ] # construct the BST root = buildBST ( preorder ) [ 0 ] # print the BST print ( "Inorder Traversal of BST is:" , end = ' ' ) # inorder on the BST always returns a sorted sequence inorder ( root ) Download Run Code Output:



Inorder Traversal of BST is : 8 10 12 15 16 20 25













(24 votes, average: 5.00 out of 5)

Loading...

Thanks for reading.