Search N elements in an unbalanced Binary Search Tree in O(N * logM) time
Given an Unbalanced binary search tree (BST) of M nodes. The task is to find the N elements in the Unbalanced Binary Search Tree in O(N*logM) time.
Examples:
Input: search[] = {6, 2, 7, 5, 4, 1, 3}. Consider the below tree
BST
Output:
Found
Not Found
Found
Found
Found
Found
Not Found
Naive Approach:
For each element, we will try to search for that element in the BST.
Time Complexity: O(N * M) as the tree is not balanced the height may become M. In that case, the overall complexity of searching will become O(N * M)
Auxiliary Space: O(1)
Efficient Approach: The operations can be performed efficiently by following the below idea:
First store the In-Order Traversals in an array and using binary search for searching the elements in that array because the inorder traversal of the BST will always give a sorted array.
Follow the below steps to solve the problem:
- Do a inorder traversal of the BST. i.e. O(M) time.
- Store the in-order traversal in the array.
- The array is sorted. As the inorder traversal of BST is in a sorted fashion.
- As it is Left Root Right. All Left elements are smaller than the root, all right elements are larger than root.
- Now simply use the binary search in the array.
- Return the answer.
Below is the Implementation of the above approach.
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std; // BST node struct TreeNode { int val; struct TreeNode *left, *right; }; // Build a new node TreeNode* newNode(int data) { TreeNode* temp = new TreeNode; temp->val = data; temp->left = NULL; temp->right = NULL; return temp; } // Function to insert a new node TreeNode* insert(TreeNode* root, int val) { TreeNode* newnode = newNode(val); TreeNode* x = root; TreeNode* y = NULL; while (x != NULL) { y = x; if (val < x->val) x = x->left; else x = x->right; } if (y == NULL) y = newnode; else if (val < y->val) y->left = newnode; else y->right = newnode; return y; } // Function for performing inorder traversal of BST void inorder(vector<int>& inord, TreeNode* root) { if (root == NULL) { return; } inorder(inord, root->left); inord.push_back(root->val); inorder(inord, root->right); } // Function to search a element in the BST bool BSTSearch(vector<int>& inord, int target) { return binary_search(inord.begin(), inord.end(), target); } void printArr(int N, vector<int>& targets, vector<int>& inorder) { for (int i = 0; i < N; i++) { if (BSTSearch(inorder, targets[i])) cout << "Found" << "\n"; else cout << "Not Found" << "\n"; } } // Driver code int main() { TreeNode* root = NULL; root = insert(root, 8); insert(root, 15); insert(root, 4); insert(root, 7); insert(root, 1); insert(root, 6); insert(root, 5); // BST Inorder - sorted array vector<int> inor; inorder(inor, root); vector<int> targets = { 6, 2, 7, 4, 5, 1, 3 }; int N = targets.size(); printArr(N, targets, inor); return 0; }
Java
// Java code to implement the approach import java.io.*; import java.util.*; // BST node class TreeNode { int val; TreeNode left, right; } class GFG { // Build a new node static TreeNode newNode(int data) { TreeNode temp = new TreeNode(); temp.val = data; temp.left = null; temp.right = null; return temp; } // Function to insert a new node static TreeNode insert(TreeNode root, int val) { TreeNode newnode = newNode(val); TreeNode x = root; TreeNode y = null; while (x != null) { y = x; if (val < x.val) { x = x.left; } else { x = x.right; } } if (y == null) { y = newnode; } else if (val < y.val) { y.left = newnode; } else { y.right = newnode; } return y; } // Function for performing inorder traversal of BST static void inorder(List<Integer> inord, TreeNode root) { if (root == null) { return; } inorder(inord, root.left); inord.add(root.val); inorder(inord, root.right); } // Function to search a element in the BST static boolean BSTSearch(List<Integer> inord, int target) { return inord.contains(target); } static void printArr(int N, int[] targets, List<Integer> inorder) { for (int i = 0; i < N; i++) { if (BSTSearch(inorder, targets[i])) { System.out.println("Found"); } else { System.out.println("Not Found"); } } } public static void main(String[] args) { TreeNode root = null; root = insert(root, 8); insert(root, 15); insert(root, 4); insert(root, 7); insert(root, 1); insert(root, 6); insert(root, 5); // BST Inorder - sorted array List<Integer> inor = new ArrayList<>(); inorder(inor, root); int[] targets = { 6, 2, 7, 4, 5, 1, 3 }; int N = targets.length; printArr(N, targets, inor); } } // This code is contributed by lokeshmvs21.
Python3
# Python code to implement the approach # Binary tree node class TreeNode: # Constructor to create a new node def __init__(self, val): self.val = val self.left = None self.right = None # Function to insert a new node def insert(root, val): newnode = TreeNode(val) x = root y = None while x != None: y = x if val < x.val: x = x.left else: x = x.right if y == None: y = newnode elif val < y.val: y.left = newnode else: y.right = newnode return y # Function for performing inorder traversal of BST def inorder(inord, root): if root == None: return inorder(inord, root.left) inord.append(root.val) inorder(inord, root.right) # Function to search an element in the BST def BSTSearch(inord, target): return target in inord def printArr(N, targets, inorder): for i in range(N): if BSTSearch(inorder, targets[i]): print("Found") else: print("Not Found") # Driver code root = None root = insert(root, 8) insert(root, 15) insert(root, 4) insert(root, 7) insert(root, 1) insert(root, 6) insert(root, 5) # BST Inorder - sorted array inor = [] inorder(inor, root) targets = [6, 2, 7, 4, 5, 1, 3] N = len(targets) printArr(N, targets, inor) # This code os contributed by ksam24000
C#
// C# code to implement the approach using System; using System.Collections.Generic; // BST node class TreeNode { public int val; public TreeNode left, right; } class GFG { // Build a new node static TreeNode NewNode(int data) { TreeNode temp = new TreeNode(); temp.val = data; temp.left = null; temp.right = null; return temp; } // Function to insert a new node static TreeNode Insert(TreeNode root, int val) { TreeNode newnode = NewNode(val); TreeNode x = root; TreeNode y = null; while (x != null) { y = x; if (val < x.val) { x = x.left; } else { x = x.right; } } if (y == null) { y = newnode; } else if (val < y.val) { y.left = newnode; } else { y.right = newnode; } return y; } // Function for performing inorder traversal of BST static void Inorder(List<int> inord, TreeNode root) { if (root == null) { return; } Inorder(inord, root.left); inord.Add(root.val); Inorder(inord, root.right); } // Function to search a element in the BST static bool BSTSearch(List<int> inord, int target) { return inord.Contains(target); } static void PrintArr(int N, int[] targets, List<int> inorder) { for (int i = 0; i < N; i++) { if (BSTSearch(inorder, targets[i])) { Console.WriteLine("Found"); } else { Console.WriteLine("Not Found"); } } } static void Main(string[] args) { TreeNode root = null; root = Insert(root, 8); Insert(root, 15); Insert(root, 4); Insert(root, 7); Insert(root, 1); Insert(root, 6); Insert(root, 5); // BST Inorder - sorted array List<int> inor = new List<int>(); Inorder(inor, root); int[] targets = { 6, 2, 7, 4, 5, 1, 3 }; int N = targets.Length; PrintArr(N, targets, inor); } } // This code is contributed by lokesh.
Javascript
// JavaScript code implementation class TreeNode { constructor(val) { this.val = val; this.left = null; this.right = null; } } function newNode(data) { const temp = new TreeNode(data); return temp; } function insert(root, val) { const newnode = newNode(val); let x = root; let y = null; while (x !== null) { y = x; if (val < x.val) x = x.left; else x = x.right; } if (y === null) y = newnode; else if (val < y.val) y.left = newnode; else y.right = newnode; return y; } function inorder(inord, root) { if (root === null) return; inorder(inord, root.left); inord.push(root.val); inorder(inord, root.right); } function BSTSearch(inord, target) { return inord.includes(target); } function printArr(N, targets, inorder) { for (let i = 0; i < N; i++) { if (BSTSearch(inorder, targets[i])) console.log('Found'); else console.log('Not Found'); } } const root = new TreeNode(null); insert(root, 8); insert(root, 15); insert(root, 4); insert(root, 7); insert(root, 1); insert(root, 6); insert(root, 5); const inor = []; inorder(inor, root); const targets = [6, 2, 7, 4, 5, 1, 3]; const N = targets.length; printArr(N, targets, inor); // This code is contributed by ksam24000
Found Not Found Found Found Found Found Not Found
Time Complexity : O(M + N * log M)
- In-order traversal takes O(M) for once
- BST Search is now optimized to O(log M) always irrespective of the height of BST.
Auxiliary Space: O(M), The In-order traversal needs to be stored in arrays.
Related Articles:
Please Login to comment...