Binary Search We have already discussed the simplest method for searching an array for a specific value (called the search value): The Linear search. The binary search algorithm is a far better method for searching sorted arrays. Suppose that we have an array of N integers sorted in ascending order. This algorithm works by repeatedly dividing the array in half until either we find an element containing the search value or determine it is not there. 3 5 7 9 10 12 17 20 24 0 29 31 37 44 50 62 71 72 80 93 100 mid 1 0 2 3 4 5 6 7 8 9 N-1 10 11 12 13 14 15 16 17 18 19 Suppose the value we seek is 80. We begin our search at the middle element of the array which is (N-1)/2. In our example N=20, we calculate (N-1)/2 = 9. We compare our search value to the value stored in the 9th element of the array which is 29. 29 is less than 80. This means that the value we seek must like between elements 10 and 19. This means that our value is potentially isolated in the upper portion of our array. So we need only concern ourselves with that portion. 31 37 44 50 62 71 72 80 93 100 10 11 12 13 14 15 16 17 18 19 Now we determine the middle element of this portion of the array: (10+19)/2 = 14 Element 14 contains the value 62 which again is less that 80, so element 15 becomes the “lower bounds” of the elements that might contain our value. 71 72 80 93 100 15 16 17 18 19 We determine the middle again which is (15 + 19)/2 which is 17.. and the value in element 17 is 80, we have found the desired value and can return 17 as the result of our search. If the value we are searching for is not in the array, then eventually we will end up looking at a portion of the array that consists of a single element, if it does not match our search value we know that the value is not in the array and we can simply return a value (-1 ) indicating that the value was not found. It is plain that the binary search algorithm yields a significant improvement over the linear search. A linear search would have performed 18 comparisons before finding our value, while the binary search performed only 3. So how can we implement this algorithm in code? Consider the following, assume the array is named arr, and our search value is contained in a variable named val: 1) With each comparison, we are looking at a range of elements in the array. We can indicate these elements by specifying a low and high index value that indicates the first and last element in the range being considered. If the first search, low=0 and high = N-1, since we are considering the entire array. 2) While low <= high a. We compute the middle index as mid = (low + high)/2 b. if val = arr[mid] then return mid c. if val < arr[mid] our search value must be to the left of the middle element, so set high = mid -1 , and search again d. if val > arr[mid] our search value must be to the right of the middle element, so set low = mid +1, and search again import java.util.Scanner; public class bsearch { public static void main(String[] args) { Scanner in = new Scanner(System.in); int numelements; char exit = ' '; int searchValue, result; System.out.println("Please enter the number of elements in the array."); numelements = in.nextInt(); int[] intArr = new int[numelements]; for(int i=0; i< numelements; i++){ System.out.println("Please enter a value for element " + i); intArr[i] = in.nextInt(); } bubble(intArr); System.out.println("The sorted array is: "); for(int i=0; i< numelements; i++) System.out.print(intArr[i] + " "); System.out.println(); while (exit != 'n' && exit != 'N') { System.out.println("please enter a value to search for "); searchValue = in.nextInt(); result = bsearch(intArr, searchValue); if (result == -1) System.out.println("The value " + searchValue + " is not in the array."); else System.out.println("The value " + searchValue + " is in element " + result); System.out.println("Enter Y to search again, N to exit."); exit = (in.next()).charAt(0); }// end while }// end main public static void bubble(int[] arr) { int temp; for (int i=0; i< arr.length; i++){ for (int j=0; j< arr.length-1; j++){ if( arr[j] > arr[j+1]) { temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; }// end swap }// end inner for }// end outter for } // end bubble public static int bsearch(int[] arr, int searchVal) { int result=-1, mid; boolean found=false; int low=0, high = arr.length-1; while (!found && low <= high) { mid = (low + high) / 2; if (arr[mid] == searchVal) { result = mid; found = true; } else if ( searchVal < arr[mid] ) high = mid-1; else low = mid + 1; } // end while return result; }// end bsearch } How efficient is the binary Search algorithm The execution time of the binary search algorithm is a function of the number of probes into the array. Let’s analyze the worst case scenario for a varying number of elements. Let N represent the number of elements in the array.. Let N = 2k -1 for k >= 1 This will give us an odd number of elements: Let K=1, then N = 1… so the maximum # probes is 1 Let K=2, then N = 3 and the array contains: 1 2 3 We can diagram this as: 2 1 3 The maximum # of probes will be 2. Let K=3, then N = 7 and the array contains: 1 2 We can diagram this as: 3 4 5 6 7 1 4 2 2 6 1 3 5 7 3 The maximum # of probes is 3… 1 probe at each “level” in the diagram Let K=4, then N = 15 and the array contains: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 We can diagram this as: 8 1 probe for middle subtree with 7 nodes subtree with 7 nodes Maximum of 3 probes 4 probes total 15 We can create a table: # Elements 1 3 7 15 31 K 1 2 3 4 5 # Probes 1 2 3 4 5 The maximum # of probes is log2 (n). Now let N be any arbitrary integer… say 10. What is the maximum number of probes? N =10 1 2 3 4 5 6 7 8 9 10 We can diagram this as: 1 5 2 1 2 8 3 6 9 3 4 4 7 10 For 10 elements the maximum number of probes is 4… the number of probes is always the same as K if N falls between 2k-1-1 and 2k -1. For example, if N=100, log2 (100+1) = 7, and 26-1 = 63 and 27-1 = 127