Show
Get this book -> Problems on Array: For Interviews and Competitive Programming In this article, we have presented the Mathematical Analysis of Time and Space Complexity of Binary Search for different cases such as Worst Case, Average Case and Best Case. We have presented the exact number of comparisons in Binary Search. Note: We have denoted the Time and Space Complexity in Big-O notation. Table of content: In short: Go through these articles to understand Binary Search completely: Binary Search is an algorithm is efficiently search an element in a given list of sorted elements. Binary Search reduces the size of data set to searched by half at each step. The iterative implementation of Bianry Search is as follows: Let us get started with the mathematical analysis of Binary Search. The best case of Binary Search occurs when: In this case, the element is found in the first step itself and this involves 1 comparison. Therefore, Best Case Time Complexity of Binary Search is O(1). Let there be N distinct numbers: a1, a2, ..., a(N-1), aN We need to find element P. There are two cases: Case 1: The element P can be in N distinct indexes from 0 to N-1.
Case 2: There will be a case when the element P is not present in the list.
There are N case 1 and 1 case 2. So, there are N+1 distinct cases to consider in total. If element P is in index K, then Binary Search will do K+1 comparisons. This is because: The element at index N/2 can be found in 1 comparison as Binary Search starts from middle. Similarly, in the 2nd comparisons, elements at index N/4 and 3N/4 are compared based on the result of 1st comparison. On this line, in the 3rd comparison, elements at index N/8, 3N/8, 5N/8, 7N/8 are compared based on the result of 2nd comparison. Based on this, we know that:
Therefore, Elements requiring I comparisons: 2^(I-1) The maximum number of comparisons = Number of times N is divided by 2 so that result is 1 = Comparisons to reach 1st element = logN comparisons I can vary from 0 to logN Total number of comparisons = 1 * (Elements requiring 1 comparison) + 2 * (Elements requiring 2 comparisons) + ... + logN * (Elements requiring logN comparisons) Total number of comparisons = 1 * (1) + 2 * (2) + 3 * (4) + ... + logN * (2^(logN-1)) Total number of comparisons = 1 + 4 + 12 + 32 + ... = 2^logN * (logN - 1) + 1 Total number of comparisons = N * (logN - 1) + 1 Total number of cases = N+1 Therefore, average number of comparisons = ( N * (logN - 1) + 1 ) / (N+1) Average number of comparisons = N * logN / (N+1) - N/(N+1) + 1/(N+1) The dominant term is N * logN / (N+1) which is approximately logN. Therefore, Average Case Time Complexity of Binary Search is O(logN). Analysis of Worst Case Time Complexity of Binary SearchThe worst case of Binary Search occurs when:
In this case, the total number of comparisons required is logN comparisons. Therefore, Worst Case Time Complexity of Binary Search is O(logN). Analysis of Space Complexity of Binary SearchIn an iterative implementation of Binary Search, the space complexity will be O(1). This is because we need two variable to keep track of the range of elements that are to be checked. No other data is needed. In a recursive implementation of Binary Search, the space complexity will be O(logN). This is because in the worst case, there will be logN recursive calls and all these recursive calls will be stacked in memory. In fact, if I comparisons are needed, then I recursive calls will be stacked in memory and from our analysis of average case time complexity, we know that the average memory will be O(logN) as well. ConclusionThe conclusion of our Time and Space Complexity analysis of Binary Search is as follows:
With this article at OpenGenus, you must have the complete idea of analyzing Binary Search algorithm. Enjoy. The Kendriya Vidyalaya Sangathan (KVS) is soon be going to release the official notification for the KVS Recruitment 2022. A total of 8339+ vacancies are expected to release for recruitment. Candidates with a Master's degree and B.Ed are eligible to appear for the recruitment process. The selection of the candidates depends on their performance in the Written Test and Interview rounds. With an expected KVS Salary range between Rs. 47,600 to Rs. 151,100, it is a golden opportunity for job seekers.
If you're seeing this message, it means we're having trouble loading external resources on our website. If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.
Binary Search Algorithm is one of the widely used searching techniques. It can be used to sort arrays. This searching technique follows the divide and conquer strategy. The search space always reduces to half in every iteration. Binary Search Algorithm is a very efficient technique for searching but it needs some order on which partition of the array will occur. Advantages of Binary Search Algorithm
Limitations of Binary Search Algorithm
Applications of Binary Search
Binary Search Pseudocode
Binary Search AlgorithmIterative approachbinarySearch(arr, size) loop until beg is not equal to end midIndex = (beg + end)/2 if (item == arr[midIndex] ) return midIndex else if (item > arr[midIndex] ) beg = midIndex + 1 else end = midIndex - 1Recursive approachbinarySearch(arr, item, beg, end) if beg<=end midIndex = (beg + end) / 2 if item == arr[midIndex] return midIndex else if item < arr[midIndex] return binarySearch(arr, item, midIndex + 1, end) else return binarySearch(arr, item, beg, midIndex - 1) return -1Binary Search Algorithm Dry Runinput: beg=0, end=4, mid=2 beg=3, end=4, mid=3 Element found at index 3, Hence 3 will get returned. 2. Given is the pictorial representation of binary search through an array of size 6 arranged in ascending order. We intend to search the element 78: Binary Search Time Complexity
Calculating Time complexity of binary search
(E.g. If a binary search gets terminated after four iterations, then k=4.)
n/(2^k)=1 => n = 2k
=>log(n) = log (2^k) (log with base 2) =>log (n) = k log (2) (log with base 2) As (log (a) = 1) (log with base 2) Therefore, => k = log (base 2) (n) Therefore, the time complexity of the Binary Search algorithm is log (base 2) n. Binary Search Space ComplexityNo auxiliary space is required in Binary Search implementation The binary search algorithm’s space complexity depends on the way the algorithm has been implemented. Two ways in which it can be implemented are:
Binary Search in CIterative Binary Search in CCode: #include <stdio.h> int binarySearch( int arr[], int item, int beg, int end) { while (beg <= end) { int midIndex = beg + (end - beg) / 2; if (arr[midIndex] == item) return midIndex; if (arr[midIndex] > item) beg = midIndex + 1; else end = midIndex - 1; } return -1; } int main(void) { int arr[] = {13, 45, 65, 16, 117, 82, 19}; int n = sizeof(arr) / sizeof(arr[0]); int item = 45; int ans = binarySearch(arr, item, 0, n - 1); if (ans == -1) printf("Element not present"); else printf("answer: %d", ans); return 0; }Output: answer: 1 Recursive Binary Search in CCode: #include <stdio.h> int binarySearch(int arr[], int item, int beg, int end) { if (end >= beg) { int midIndex = beg + (end - beg) / 2; if (arr[midIndex] == item) return midIndex; if (arr[midIndex] < item) return binarySearch(arr, item, beg, midIndex - 1); return binarySearch(arr, item, midIndex + 1, end); } return -1; } int main(void) { int arr[] = {13, 45, 65, 16, 117, 82, 19}; int n = sizeof(arr) / sizeof(arr[0]); int item = 45; int ans = binarySearch(arr, item, 0, n - 1); if (ans == -1) printf("Element not present"); else printf("answer: %d", ans); return 0; }Output: answer: 1 Binary Search in JAVAIterative Binary Search in JAVACode: class BinarySearch { int binarySearch(int arr[], int item, int beg, int end) { while (beg <= end) { int midIndex = beg + (end - beg) / 2; if (arr[midIndex] == item) return midIndex; if (arr[midIndex] > item) beg = midIndex + 1; else end = midIndex - 1; } return -1; } public static void main(String args[]) { BinarySearch ob = new BinarySearch(); int arr[] = {13, 45, 65, 16, 117, 82, 19}; int n = arr.length; int item = 45; int ans = ob.binarySearch(arr, item, 0, n - 1); if (ans == -1) System.out.println("Element not present"); else System.out.println("answer: "+ans); } }Output: Recursive Binary Search in JAVACode: class BinarySearch { int binarySearch(int arr[], int item, int beg, int end) { if (end >= beg) { int midIndex = beg + (end - beg) / 2; if (arr[midIndex] == item) return midIndex; if (arr[midIndex] < item) return binarySearch(arr, item, beg, midIndex - 1); return binarySearch(arr, item, midIndex + 1, end); } return -1; } public static void main(String args[]) { BinarySearch ob = new BinarySearch(); int arr[] = {13, 45, 65, 16, 117, 82, 19}; int n = arr.length; int item = 45; int ans = ob.binarySearch(arr, item, 0, n - 1); if (ans == -1) System.out.println("Element not present"); else System.out.println("answer: "+ans); } }Output: Binary Search in C++Iterative Binary Search in C++Code: #include <iostream> using namespace std; int binarySearch(int arr[], int item, int beg, int end) { while (beg <= end) { int midIndex = beg + (end - beg) / 2; if (arr[midIndex] == item) return midIndex; if (arr[midIndex] > item) beg = midIndex + 1; else end = midIndex - 1; } return -1; } int main(void) { int arr[] = {13, 45, 65, 16, 117, 82, 19}; int n = sizeof(arr) / sizeof(arr[0]); int item = 45; int ans = binarySearch(arr, item, 0, n - 1); if (ans == -1) printf("Element not present"); else printf("answer: %d", ans); }Output: Recursive Binary Search in C++Code: #include <iostream> using namespace std; int binarySearch(int array[], int item, int beg, int end) { if (end >= beg) { int midIndex = beg + (end - beg) / 2; if (array[midIndex] == item) return midIndex; if (array[midIndex] < item) return binarySearch(array, item, beg, midIndex - 1); return binarySearch(array, item, midIndex + 1, end); } return -1; } int main(void) { int arr[] = {13, 45, 65, 16, 117, 82, 19}; int n = sizeof(arr) / sizeof(arr[0]); int item = 45; int ans = binarySearch(arr, item, 0, n - 1); if (ans == -1) printf("Element not present"); else printf("answer: %d", ans); }Output: Binary Search in PythonIterative Binary Search in PythonCode: def binarySearch(arr, item, beg, end): while beg <= end: mid = beg + (end - beg)//2 if arr[mid] == item: return mid elif arr[mid] > item: beg = mid + 1 else: end = mid - 1 return -1 arr = [13, 45, 65, 16, 117, 82, 19] item = 45 ans = binarySearch(arr, item, 0, len(arr)-1) if ans != -1: print("answer: " + str(ans)) else: print("Element not present")Output: Recursive Binary Search in PythonCode: def binarySearch(arr, item, beg, end): if end >= beg: midIndex = beg + (end - beg)//2 if arr[midIndex] == item: return midIndex elif arr[midIndex] < item: return binarySearch(arr, item, beg, midIndex-1) else: return binarySearch(arr, item, midIndex + 1, end) else: return -1 arr = [13, 45, 65, 16, 117, 82, 19] item = 45 ans = binarySearch(arr, item, 0, len(arr)-1) if ans != -1: print("answer: " + str(ans)) else: print("Element not present")Output: Binary Search ExampleExample1: Your task is to find the first and last occurrence of the given element in the array. If an element is not present, return -1. Assuming sorting here is in ascending order. Example: Input 7 1 2 5 5 5 5 6 5 Output 2 5 Code in Java: import java.util.*;
class Demo {
public static void main ( String[] args ) {
Scanner sc = new Scanner( System.in );
int n = sc.nextInt();
int[] arr = new int[n];
for( int i = 0 ; i < n ; i++ )
{
arr[i] = sc.nextInt();
}
int item = sc.nextInt();
int beg = 0, end = 0;
for( int i = 0 ; i < n ; i++ )
{
if( arr[i] == item )
{
beg = i;
break;
}
else{
beg = -1;
}
}
for( int i = arr.length - 1 ; i > 0; i-- )
{
if( arr[i] == item )
{
end = i;
break;
}
}
if(beg == -1)
{
System.out.println( -1 );
}
else {
System.out.println( beg + " " + end );
}
}
} Code in C++:#include <iostream> using namespace std; int main(void) { int n; cin>>n; int arr[n]; for( int i = 0 ; i < n; i++) cin>>arr[i]; int item; cin>>item; int beg = 0, end = 0; for( int i = 0 ; i < n ; i++ ) { if( arr[i] == item ) { beg = i; break; } else{ beg = -1; } } for( int i = n - 1 ; i > 0; i-- ) { if( arr[i] == item ) { end = i; break; } } if(beg == -1) { cout<<"-1"; } else { cout<<beg<<" "<<end; } }Code in C:#include <stdio.h> int main() { int n; scanf("%d ", &n); int arr[n]; for( int i = 0 ; i < n; i++) scanf("%d ",&arr[i]); int item; scanf("%d ",&item); int beg = 0, end = 0; for( int i = 0 ; i < n ; i++ ) { if( arr[i] == item ) { beg = i; break; } else{ beg = -1; } } for( int i = n - 1 ; i > 0; i-- ) { if( arr[i] == item ) { end = i; break; } } if(beg == -1) { printf("%d ",-1); } else { printf("%d %d",beg,end); } }Complexity of Searching, Insertion and Deletion in Binary TreeA tree is binary when a node can have at most two children. Let’s define the complexity of searching, insertion & deletion in a binary tree with an example. E.g. The figure given below is a binary tree. If we have to search for element 7, we will have to traverse all the elements to reach that element, therefore to perform searching in a binary tree, the worst-case complexity= O(n). If we have to insert an element as the left child of element 7, we will have to traverse all the elements, therefore performing insertion in a binary tree, the worst-case complexity= O(n). If we have to delete element 7, we will have to traverse all the elements to find it, therefore performing deletion in a binary tree, the worst-case complexity= O(n). Complexity of Searching, Insertion and Deletion in Binary Search Tree (BST)Binary Search Tree (BST) is considered as a special type of binary tree where the values are arranged in the following order: left child < parent node < right child. Let’s define the complexity of searching, insertion & deletion in a binary search tree with an example. E.g. The figure given below is a binary search tree. If we have to search for element 3, will have to traverse all the elements to reach that element, therefore to perform searching in a binary search tree, the worst-case complexity= O(n). In general, the time complexity is O(h) where h = height of binary search tree. If we have to insert an element 2, we will have to traverse all the elements to insert it as the left child of 3. Therefore, to perform insertion in a binary search tree, the worst-case complexity= O(n) whereas the time complexity in general = O(h). Suppose we have to delete the element 3. In that case, we will have to traverse all the elements to find it, therefore performing deletion in a binary tree, the worst-case complexity= O(n) whereas the time complexity in general = O(h). Complexity of Searching, Insertion and Deletion in AVL TreeAVL(Adelson-Velskii and Landis) tree is a binary search tree which is also known as height balanced tree as it has a property in which the difference between the height of the left sub-tree and the right sub-tree can never be more than 1. Let’s define the complexity of searching, insertion & deletion in AVL tree with an example. E.g. The figure given below is an AVL tree. If we have to search for element 5, will have to traverse all the elements to reach that element i.e. in the order 30,14,5 = 3 = log n , therefore to perform searching in an AVL tree, the worst-case complexity= O(log n). If we have to insert an element 92, we will have to traverse all the elements in order 30, 42, 71 to insert it as the right child of 71. Therefore, to perform insertion in an AVL tree, the worst-case complexity= O(log n). If we have to delete the element 71, we will have to traverse all the elements to find it in the order 30, 42, 71. Therefore to perform deletion in an AVL tree, the worst-case complexity= O(log n). Big O for Binary SearchBig O notation shows the number of operations that an algorithm will perform. It finds the upper bound that gives the worst-case running time complexity. It helps you understand how fast an algorithm is growing and allows you to compare the growth with others. When the number of steps are counted, you divide the range into half and then process it. This process stops once both the upper and the lower bounds cross. This way you check the entry every time as you have half of the number of entries to check each time. Putting this into a formula as a recurrence T(n) we get: T(n)=T(n/2)+1 (Binary search recurrence relation) With base case T(1)=1. By applying any variant of the Master Theorem, you get T(n) ∈ O(log (n)) Running Time of Binary SearchBinary search halves the size of portion that is reasonable after every incorrect guess. If binary search makes a wrong guess, the portion of the array that contains reasonable guesses is reduced to half. For eg. if the portion had 40 elements then the incorrect guess comes down to 20. If we start performing binary search on an array of 16 elements then the incorrect guessed will be reduced to length 8, then 4, then 2 and then 1. No more guesses occur once the reasonable portion comes down to just 1. 1 portion element can either be correct or incorrect and we have reached our result. So, for an array of length 16 elements, binary search requires five guesses at most. Similarly for 32 elements, binary search will require at most 6 guesses to get the answer. We can see a pattern being formed here i.e., we require one more guess to get the result if the number of elements is doubled. Let there be m number of guesses for an array of length n, then for an array of length 2n, the length cut down after the 1st guess will be n. Now, the number of guesses will become m+1. (Taking up the general case of an array of length n, we can say that the number of time we are repeatedly reducing the length of n to half until we reach the value 1, plus one. We can write this mathematically with the base-2 logarithm of n.) The worst case in binary search is achieved when the integers are equal which can be significant when the encoding lengths are large, like large integer types or long strings. This would make the comparison between elements expensive, also comparing the floating-point values are often more expensive than the comparison done between integers or short strings. RB TreeRB Tree (Red Black Tree) is a self-balancing binary search tree where left child < parent < right child. Each node in the RB tree is either red or black in color. These colors ensure that the tree maintains its balance when insertion or deletion of nodes is performed. Properties:
Time Complexity of RB TreeFor searching, the time complexity is O(log n). For insertion, the time complexity is O(log n). For deletion, the time complexity is O(log n). Rotation Operation on RB TreeLR (Left Right) Rotation RR (Right Right) Rotation Insertion in RB TreeAlgorithm: RB-INSERT (T, z) 1. y ← nil [T] 2. x ← root [T] 3. while x ≠ NIL [T] 4. do y ← x 5. if key [z] < key [x] 6. then x ← left [x] 7. else x ← right [x] 8. p [z] ← y 9. if y = nil [T] 10. then root [T] ← z 11. else if key [z] < key [y] 12. then left [y] ← z 13. else right [y] ← z 14. left [z] ← nil [T] 15. right [z] ← nil [T] 16. color [z] ← RED 17. RB-INSERT-FIXUP (T, z)After inserting a node in RB Tree, the color of the nodes are fixed using the following algorithm to maintain the balance of the tree. RB_INSERT_FIXUP(T,z) 1. While color [p[z]] = RED 2. Do if p[z] = left [p[p[z]] 3. then y ← right [p[p[z]]] 4. if color [y] = RED 5. then color [p[z]] ← BLACK //Case 1 6. color [y] ← BLACK //Case 1 7. color [p[p[z]]] ← RED //Case 1 8. Z ← p[p[z]] //Case 1 9. else if z = right [p[z]] 10. then z ← p[z] //Case 2 11. LEFT_ROTATE(T,z) //Case 2 12. color [p[z]] ← BLACK //Case 3 13. color [p[z]] ← RED //Case 3 14. RIGHT_ROTATE(T,p[p[z]]) //Case 3 15. else (same as then clause with “right” & “left” exchange) 16. color [root[T]] ← BLACKDifference between Binary Tree and Binary Search Tree
This brings us to the end of the blog on Binary Search Algorithm. We hope that you enjoyed it and were able to learn the concept of Binary Search Algorithm well. If you wish to upskill, you can check out Great Learning Academy’s Free online courses! |