Chapter 14 Searching and Sorting Go Section 1 - Sequential or Linear Search Go Section 2 - Binary Search Go Section 3 - Selection Sort Go Section 4 - Insertion Sort Go Section 5 - Merge Sort 1 Searches and Sorts There are two search algorithms and three sort algorithms that you need to know for the AP Exam: • Sequential Search also called Linear Search • Binary Search • Selection Sort • Insertion Sort • Merge Sort We will discuss each and note some important facts about each one. 2 Chapter 14 - Section 1 Sequential or Linear Search 3 Sequential Search or Linear Search Sequential Search also called Linear Search can be performed on a sorted or unsorted array. As the name indicates, the search process begins at the start of the list (usually a standard array) and checks the first element to see if it is the target value. If it is not, the process continues with each element being checked until the value is found or the end of the list is reached. When it is found, the position of the target value (it’s index) is returned by the method. If the target value is NOT found, then the value -1 is returned. 4 Sequential Search of an Array of ints Only one loop is necessary for Sequential Search. The code is usually contained in a method and a target value being searched for is passed to it. public static int sequentialSearchInts (int [ ] arr, int searchValue) { for (int i = 0; i < arr.length; i++) { if (arr [ i ] == searchValue) { return i; // if found return the index of the target value } } return -1; // if target value NOT found return -1 } 5 Sequential Search of an Array of ints The variable checks can be added to see how many checks are needed to find the target value. public static int sequentialSearchInts (int [ ] arr, int target) { checks = 0; for (int i = 0; i < arr.length; i++) { checks++; // increment as a value is checked if (arr [ i ] == target) { System.out.println(”Found the value after " + checks + " checks!"); return i; } } System.out.println("The value was NOT found by Linear Search!"); return -1; } 6 Sequential Search of a 2D Array of ints A two-dimensional array can be searched also, but two loops are necessary. public static int TwoDArraySearchInts (int [ ] [ ] arr, int target) { for (int row = 0; row < arr.length; row ++) { for (int col = 0; col < arr[row].length; col++) { if (arr [ row ][col] == target) { return i; // if found return the index of the target value } } } return -1; // if target value NOT found return -1 } 7 Sequential Search of an Array of Strings The code is almost the same for a list of objects, except the equals method is used for the type of object. Here the array contains String values: public static int sequentialSearchStrings (String [ ] arr, String target) { for (int i = 0; i < arr.length; i++) { if ( arr [ i ]. equals (target) ) { return i; // if found return the index of the target value } } return -1; // if target value NOT found return -1 } 8 Sequential Search of an Array of Students The code is almost the same for a list of objects, except the equals method is used for the type of object. Here the array contains String values: public static int linearSearchStudents (Student [ ] arr, Student target) { for (int i = 0; i < arr.length; i++) { if ( arr [ i ]. equals (target) ) { return i; // if found return the index of the target value } } return -1; // if target value NOT found return -1 } Notice the code is not any different from the code for searching strings because the Student class has an equals method. 9 Sequential Search of an ArrayList of Students The code is almost the same for an ArrayList of Student objects. We only need to replace [ ] with a call to the get method: public static int search (ArrayList <Student> arr, Student target) { for (int i = 0; i < arr.size(); i++) { if ( arr.get(i). equals (target) ) { return i; // if found return the index of the target value } } return -1; // if target value NOT found return -1 } Notice the code is almost the same as searching a standard array of Student objects. 10 Chapter 14 - Section 2 Binary Search 11 Binary Search Binary Search must be performed on a sorted array. If you try to use it on an unsorted list, you will get erroneous results. You may be told a value was not found when it was actually in the list. Binary Search is a divide and conquer algorithm. The search process begins at the middle of the list. The midpoint is calculated by using the index values of the first array location and the last array location. The code has two variables left and right that refer to those index values. If the value at the midpoint index is the target value, then the search is over and the index value of the midpoint is returned. If the target value is not stored at the midpoint index, then the process continues using a comparison of the target value and the value at the midpoint to see which half of the array will be excluded from the 12 remainder of the search process. Binary Search Code public static int binarySearchInts (int [] arr, int target) { checks = 0; int left = 0; int right = arr.length - 1; while (left <= right) { checks++; int midpoint = (left + right) / 2; if (arr[midpoint] == target) { System.out.println(”Found after " + checks + " checks!"); return midpoint; } else if (arr[midpoint] < target) left = midpoint + 1; else right = midpoint - 1; } System.out.println("The value was NOT found by Binary Search!"); return -1; // if target not found return -1 } 13 Binary Search The Binary Search algorithm uses the following code: midpoint = (left + right) / 2; It is extremely important that you are aware that midpoint, left, and right are int variables, because if the array has 8 elements, then when the search starts, the value of left is 0 and the value of right is 7. (0 + 7) / 2 is equal to 3 NOT 3.5 because this is integer division which truncates the remainder. So the first midpoint value would be the index 3. If the target value is found, then the variables left and right get new values and a new midpoint is checked. 14 Binary Search Because the Binary Search algorithm successively divides the array in half during each check for the target value, its name is representative of what is happening. Mathematically, we can express the number of checks Binary Search takes to find a target value as log2n. That is “the log base 2 of n”. So how many checks need to be done to find a target value in an array of size 8? log28 which is equal to log2(23) which is equal to 3. Actually because of the integer division truncation of the statement midpoint = (left + right) / 2; it takes one more (4) when there are eight if the target value is in the last index 7. So we will summarize this for you on the next slide: 15 Binary Search’s Efficiency is log2n + 1 If Binary Search looks for a target value in an array of size 7, it takes at most 3 checks to see if the target value is in the list. The numbers in red indicate the 1st, 2nd, or 3rd checks that would be made in finding any of the values in the array or one not in it. [0] [1] [2] [3] [4] [5] [6] 5 10 15 20 25 30 35 3 2 3 1 3 2 3 However, notice the numbers when there are 8 values in the list: [0] [1] [2] [3] [4] [5] [6] [7] 5 10 15 20 25 30 35 40 3 2 3 1 3 2 3 4 16 The Number of Checks for Binary Search So here is the rule on how to find the number of checks it takes to find a target value in an array: You take the log base 2 of the next highest power of 2. value of n 0 – 7 elements takes … log2(8) or log2(23) = 3 checks 8 – 15 elements takes … log2(16) or log2(24) = 4 checks 16 – 31 elements takes … log2(32) or log2(25) = 5 checks 32 - 63 elements takes … log2(64) or log2(26) = 6 checks 64 - 127 elements takes … log2(128) or log2(27) = 7 checks This can be summarized in general as: log2n + 1 So you can see when n is 8 it takes 4 checks: log28 + 1 = 3 + 1 = 4 17 Recursive Binary Search 18 Recursive Binary Search Code public int binarySearch (int[] arr, int target) { int pos = recurBinarySearch (arr, target, 0, arr.length - 1); return pos; } private int recurBinarySearch (int[] arr, int target, int left, int right) { if (left > right) return -1; else { int midpoint = (left + right) / 2; if (arr[midpoint] == target) return midpoint; else if (arr[midpoint] < target) return recurBinarySearch (arr, target, midpoint + 1, right); else return recurBinarySearch (arr, target, left, midpoint - 1); } } 19 Efficiency of the Searches The efficiency of Sequential Search is pretty good for small sized arrays up to size 1000. Computer processors are fast enough that it would not matter if you are performing a Sequential Search or a Binary Search. However, if the array is much larger, above size 1000, then Binary Search will always be faster than Sequential Search. Here is a table that shows the Best, Worst, and Average case efficiencies of Sequential and Binary Search. Search of n elements Best Case Worst Case Average Case Sequential 1 check n checks n / 2 checks Binary 1 check log2n checks log2n checks Mathematically log2n is better than n. Graphing y = log n and y = n shows you why. As n increases log n doesn’t increase as fast as n. 20 Chapter 14 - Section 3 Selection Sort 21 Selection Sort Selection Sort gets its name from the fact that during the first “pass”, the smallest element in the array is “selected” and swapped to the first position in the array. It does this by keeping track of the index where the current smallest element is located using the variable minIndex. As it makes a pass it continually checks all values in order to see if they are smaller than the current smallest element. On the second pass, the next to the smallest element is swapped into the second position in the array and so on until the largest element is placed in the last position in the array. Using this approach, the elements end up in “ascending order” in the array (smallest to largest). The algorithm can also be written to place the largest element in the first position in the array, the next to the largest element in the second position and so on until the elements are in reverse or “descending order”. (largest to smallest ). 22 Selection Sort The main efficiency of Selection Sort is that there is only one swap per pass. In computer time, swaps take longer to process than just checking something. So a lot of swaps can be bad for efficiency. The code can also be written to swap the largest element to the last location of the array, the next to the largest element into the next to the last location in the array and so on. In this case the elements will be in ascending order. Its just that we are manipulating the largest item during each pass instead of the smallest. The code can also be written to swap the smalles element to the last location of the array, the next to the smallest element into the next to the last location in the array and so on. In this case the elements will be in descending order. Its just that we are manipulating the smallest item during each pass instead of the smallest. 23 Selection Sort Let’s say that an array has the following values stored in it with the element 18 stored in index 0: 18 13 6 23 8 Selection Sort finds that the smallest element is in index 2, so it swaps 6 with the first element 18 stored in index 0. 6 13 18 23 8 First pass over! 6 is out of the sorting process. Selection Sort finds that the next smallest element is in index 4, so it swaps 8 with the first element in the part of the array still being sorted, 13. 6 8 18 23 13 Second pass over! 8 is out of the sorting process. Selection Sort finds that the next smallest element is in index 4, so it swaps 13 with the first element in the part of the array still being sorted, 18. 6 8 13 23 18 Third pass over! 13 is out of the sorting process. Selection Sort finds that the next smallest element is in index 4, so it swaps 18 with the first element in the part of the array still being sorted, 23. 6 8 13 18 23 Fourth pass over! 18 is out of the sorting process. On the last pass 23 is already in order so no swap is made. 24 Selection Sort Ascending Order for ints public static void selectionSortInts(int [ ] arr) { swaps = 0; int minIndex; for (int i = 0; i < arr.length - 1; i++) { minIndex = i; for (int index = i + 1; index < arr.length; index++) if (arr[index] < arr[minIndex]) minIndex = index; int temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex]= temp; swaps++; } System.out.println("It took " + swaps + " swaps using Selection Sort!"); } 25 Selection Sort Descending Order for ints public static void selectionSortInts(int [ ] arr) { swaps = 0; int maxIndex; for (int i = 0; i < arr.length - 1; i++) { maxIndex = i; for (int index = i + 1; index < arr.length; index++) if (arr[index] > arr[maxIndex]) maxIndex= index; int temp = arr[i]; arr[i] = arr[maxIndex]; arr[maxIndex]= temp; swaps++; } System.out.println("It took " + swaps + " swaps using Selection Sort!"); } 26 Using compareTo for Sorting To be able to sort String values, we need to use the compareTo method of the String class. If we need to sort values of another kind of object, then we need to make sure there is a compareTo method of that class. Let’s review the information on the compareTo method of the String class originally given you in the Chapter 7 PowerPoint on Strings. 27 Sect 6 - int compareTo (String other) Consider the code: String s1 = reader.nextLine(); String s2 = reader.nextLine(); In the call of the method compareTo below, s1 is this and s2 is other ….. if (s1.compareTo(s2) == 0) and the compareTo method returns one of the following values when it is made: • a negative integer if this is lexicographically less than other • 0 if this is equal to other • a positive integer if this is lexicographically greater than other One thing the compareTo() method is valuable for is to help us sort String values in a list. We will eventually do this. 28 Sect 6 - int compareTo (String other) The following code compares the string values in word1 and word2 to identify the lexicographical order of word1 and word2. String word1 = reader.nextLine(); String word2 = reader.nextLine(); lexicographical indicates alphabetical order if (word1.compareTo (word2) < 0) System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2) == 0) System.out.println(word1 + “ is equal to ” + word2); 29 Sect 6 - int compareTo (String other) If word1 comes before word2, then a negative int value is returned by word1.compareTo (word2 ). If word1 comes after word2, then a positive int value is returned. If word1 exactly equals word2, then zero is returned. if (word1.compareTo (word2 ) < 0) System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2 ) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2 ) == 0) System.out.println(word1 + “ is equal to ” + word2); 30 Sect 6 - int compareTo (String other) In this code, word1 is the receiver object this and word2 is other. String word1 = “a”; String word2 = “b”; if (word1.compareTo (word2) < 0) Note that word1 is calling the method. System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2) == 0) System.out.println(word1 + “ is equal to ” + word2); Output: “a comes before b” Note: “a”.compareTo(“b”) returns -1 based on the Unicode (ASCII) values for “a” and “b” … 97 - 98 = -1 31 Sect 6 - int compareTo (String other) In this code, word1 is the receiver object this and word2 is other. String word1 = “a”; String word2 = “c”; if (word1.compareTo (word2) < 0) System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2) == 0) System.out.println(word1 + “ is equal to ” + word2); Output: “a comes before b” Note: “a”.compareTo(“c”) returns -2 based on the Unicode values for “a” and “c” … 97 - 99 = -2 32 Sect 6 - int compareTo (String other) In this code, word1 is the receiver object this and word2 is other. String word1 = “apple”; String word2 = “banana”; if (word1.compareTo (word2) < 0) System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2) == 0) System.out.println(word1 + “ is equal to ” + word2); Output: “apple comes before banana” Note: “apple”.compareTo(“banana”) returns -1 based on the Unicode values for “a” and “b” … 97 - 98 = -1. Only the first two characters are compared, because they are different. 33 Sect 6 - int compareTo (String other) In this code, word1 is the receiver object this and word2 is other. String word1 = “b”; String word2 = “a”; if (word1.compareTo (word2) < 0) System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2) == 0) System.out.println(word1 + “ is equal to ” + word2); Output: “b comes after a” Note: “b”.compareTo(“a”) returns +1 based on the Unicode values for “b” and “a” … 98 - 97 = 1 34 Sect 6 - int compareTo (String other) In this code, word1 is the receiver object this and word2 is other. String word1 = “d”; String word2 = “a”; if (word1.compareTo (word2) < 0) System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2) == 0) System.out.println(word1 + “ is equal to ” + word2); Output: “b comes after a” Note: “d”.compareTo(“a”) returns +3 based on the Unicode values for “d” and “a” … 100 - 97 = 3 35 Sect 6 - int compareTo (String other) In this code, word1 is the receiver object this and word2 is other. String word1 = “bear”; String word2 = “bearcats”; if (word1.compareTo (word2) < 0) System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2) == 0) System.out.println(word1 + “ is equal to ” + word2); Output: “banana comes after apple” Note: “bear”.compareTo(“bearcats”) returns -4 based on the fact that the words are the same but the second one has 4 additional characters. “bearcats”.compareTo(“bear”) returns +4. 36 Sect 6 - int compareTo (String other) In this code, word1 is the receiver object this and word2 is other. String word1 = “bearclaw”; String word2 = “bearcats”; if (word1.compareTo (word2) < 0) System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2) == 0) System.out.println(word1 + “ is equal to ” + word2); Output: “banana comes after apple” Note: “bearclaw”.compareTo(“bearcats”) returns +11 based on the Unicode values for “l” and “a” … 108 - 97 = 11. Only the first two characters that are different are compared. 37 Sect 6 - int compareTo (String other) In this code, word1 is the receiver object this and word2 is other. String word1 = “bearcats”; String word2 = “bearclaw”; if (word1.compareTo (word2) < 0) System.out.println(word1 + “ comes before ” + word2); else if (word1.compareTo (word2) > 0) System.out.println(word1 + “ comes after ” + word2); else if (word1.compareTo (word2) == 0) System.out.println(word1 + “ is equal to ” + word2); Output: “banana comes after apple” Note: “bearclaw”.compareTo(“bearcats”) returns -11 based on the Unicode values for “a” and “l” … 97 - 108 = -11. Only the first two characters that are different are compared. 38 Writing a Student Class compareTo Method You will also write a compareTo Method in the Student class. It can be used to sort a list of Student objects. A class like Student or Person can only properly include a compareTo method if it implements the Comparable interface using templating in the class definition line: public class Person implements Comparable <Person> Let’s look at what a compareTo method of the Person class would look like on the next slide. 39 CompareTo Method for the Person class public int compareTo(Person other) // note the parameter is Person not Object { if (! (other instanceof Person )) throw new IllegalArgumentException("Parameter must be a Person."); if( this.name.compareTo(other.name) == 0) { if ( this.address.equals(other.address) ) return 0; else if ( this.address.compareTo(other.address) < 0 ) return -1; else // if ( this.address.compareTo(other.address) > 0) return 1; } else if ( this.name.compareTo(other.name) < 0 ) return -1; else // if ( this.name.compareTo(other.name) > 0 ) return 1; } 40 The Selection Sort Code for Strings public static void selectionSortStrings(String [ ] arr) { swaps = 0; int minIndex; for (int i = 0; i < arr.length - 1; i++) { minIndex = i; for (int index = i + 1; index < arr.length; index++) if (arr[index].compareTo(arr[minIndex]) < 0) minIndex = index; int temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex]= temp; swaps++; } System.out.println("It took " + swaps + " swaps using Selection Sort!"); } 41 The Selection Sort Code for Students public static void selectionSortStudents(Student [ ] arr) { swaps = 0; int minIndex; for (int i = 0; i < arr.length - 1; i++) { minIndex = i; for (int index = i + 1; index < arr.length; index++) if (arr[index].compareTo(arr[minIndex]) < 0) minIndex = index; int temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex]= temp; swaps++; } System.out.println("It took " + swaps + " swaps using Selection Sort!"); } 42 Selection Sort Note that all versions of the algorithm have a nested loop structure. If there are n elements in the array, the outer loop runs approximately n times and the inner for loop runs approximately n times. This fact causes this algorithm to have an efficiency on the order of n * n or n2. Actually for this version of Selection Sort, the outside for loop runs n - 1 times. The inside loop runs a number of times based on the outside loop lcv: During first iteration of outside loop, the inner loop runs n times. During second iteration of outside loop, the inner loop runs n - 1 times. During third iteration of outside loop, the inner loop runs n - 2 times. During fourth iteration of outside loop, the inner loop runs n - 3 times. 43 and so on. Chapter 14 - Section 4 Insertion Sort 44 Insertion Sort Insertion Sort gets its name from the fact that during each “pass”, the element being sorted is being “inserted” into its proper position in the array. The position is temporary if other elements when they are sorted later move the element to a new position. This is similar to placing cards in your hand in order, as they are dealt to you one at a time. The algorithm begins with the second element in the array. If it is smaller than the first element, then the two elements are swapped. Next, the third element in the array is tested to see if it is smaller than the second element. If it is, then the two are swapped. If the third element was swapped with the second, it is then tested to see if it is smaller than the first element. If it is, then they are swapped. The next slide shows an example. 45 Insertion Sort Let’s say that an array has the following values stored in it with the element 18 stored in index 0: 18 13 6 23 Since Insertion Sort always begins with the second element it starts with 13 to see is it is smaller than 18. If it is then it swaps.13 and 18. 13 18 6 23 The first pass is over! As the second pass begins, Insertion Sort checks to see if 6 (above) is less than 18. If it is then it swaps them, so temporarily we have … 13 6 18 23 But the second pass is NOT over! Then Insertion Sort checks to see if 6 is less than 13. If it is then it swaps them and we have … 6 13 18 23 The second pass is over! As the third pass begins, Insertion Sort checks to see if 23 is less than 18. It isn’t so no swap is made and the third pass is over! 46 Insertion Sort public static void insertionSortInts(int[] arr) { swaps = 0; int itemToInsert, j; boolean stillLooking; for (int k = 1; k < arr.length; k++) { itemToInsert = arr[k]; j = k - 1; stillLooking = true; while ((j >= 0) && stillLooking) { if (itemToInsert < arr[j]) { arr[j + 1] = arr[j]; j--; } else stillLooking = false; } arr[j + 1] = itemToInsert; swaps++; } System.out.println("It took " + swaps + " swaps to sort this array!"); } 47 Insertion Sort with String Values public static void insertionSortStrings (String [ ] arr) { swaps = 0; int itemToInsert, j; boolean stillLooking; for (int k = 1; k < arr.length; k++) { itemToInsert = arr[k]; j = k - 1; stillLooking = true; while ((j >= 0) && stillLooking) { if (itemToInsert.compareTo(arr[j]) < 0) { arr[j + 1] = arr[j]; j--; } else stillLooking = false; } arr[j + 1] = itemToInsert; swaps++; } System.out.println("It took " + swaps + " swaps to sort this array!"); } 48 Insertion Sort Note that the algorithm has a nested for loop structure. If there are n elements in the array, the outer loop runs approximately n times and the inner for loop runs approximately n times. This fact causes this algorithm to have an efficiency on the order of n * n or n2. Actually for this version of Insertion Sort, the outside for loop runs n - 1 times. The inside loop runs a number of times based on the outside loop lcv: During first iteration of outside loop, the inner loop runs 1 time. During second iteration of outside loop, the inner loop runs 2 times. During third iteration of outside loop, the inner loop runs 3 times. During fourth iteration of outside loop, the inner loop runs 4 times. and so on up to n-1 times on the last iteration of the outside loop. 49 Chapter 14 - Section 5 Merge Sort 50 Merge Sort The Merge Sort algorithm is a divide and conquer algorithm. It recursively divides the original array into two equal parts It does this by copying the left half into one temporary array and the right half into another temporary array. If the size of either array is larger than two, then it divides them in half again copying the left most part into another temporary array and the right half into another temporary array. When the left and right arrays contain only one element each, then the Merge part of the algorithm places the two elements back into an array in the correct order. This happens at all levels of recursion and produces a totally sorted array of elements. This will be demonstrated for you in class with sorting cups, but it can be show here on the next slide. 51 Merge Sort Let’s say that an array has the following values stored in it with the element 18 stored in index 0. The underlined elements show how they are split in half and how they are merged back together. 18 13 6 23 15 14 9 3 18 13 6 23 15 14 9 3 arrays are split in half 18 13 6 23 15 14 9 3 arrays split in half again 18 13 6 23 15 14 9 3 arrays split in half again 13 18 6 23 14 15 3 9 elements merged in order 6 13 18 23 3 9 14 15 elements merged in order 3 6 9 13 14 15 18 23 elements merged in order With n elements, there are log2n subdivisions. This gives an efficiency of n*log2n which is better than n*n or n2. This means that Merge Sort is more efficient than Selection Sort or Insertion Sort which are both n2 sorts. 52 Merge Method Code For the AP Exam, you only need to be familiar with the Merge part of the Merge Sort algorithm, so we will show you only the Merge method here: (this is the first part) private static void merge (int [] a, int[] temp, int from, int middle, int to) { int i = from, j = middle + 1, k = from; // While both arrays have elements left unprocessed: while (i <= middle && j <= to) { if (a[i] < a[j]) // compare the first one in each of the two "subarrays" { temp[k] = a[i]; i++; } else { temp[k] = a[j]; j++; } k++; } 53 Merge Method Code For the AP Exam, you only need to be familiar with the Merge part of the Merge Sort algorithm, so we will show you only the Merge method here: (this is the second part) // Copy the tail of the first half, if any, into temp: while (i <= middle) { temp[k] = a[i]; // Or simply temp[k++] = a[i++] i++; k++; } // Copy the tail of the second half, if any, into temp: while (j <= to) { temp[k] = a[j]; // Or simply temp[k++] = a[j++] j++; k++; } // Copy temp back into a for (k = from; k <= to; k++) a[k] = temp[k]; } // end merge method 54 Merge Method Code For the AP Exam, you only need to be familiar with the Merge part of the Merge Sort algorithm, so we will show you only the Merge method here: public static void merge (int[ ] a, int[ ] copyBuffer, int low, int middle, int high) { // initialize i1 and i2 to the first items in each subarray int i1 = low, i2 = middle + 1; // Interleave items from the subarrays into the copyBuffer in such a way // that order is maintained. for (int i = low; i <= high; i++) { if (i1 > middle) copyBuffer[i] = a[i2++]; // first subarray exhausted else if (i2 > high) copyBuffer[i] = a[i1++]; // second subarray exhausted else if (a[i1] < a[i2]) copyBuffer[i] = a[i1++]; // item in first subarray is less else copyBuffer[i] = a[i2++]; // item in second subarray is less } for (int i = low; i <= high; i++) // copy sorted items back into a[i] = copyBuffer[i]; // proper position in a } // end merge method 55 Search & Sort Summary Algorithm How it Works Sequential Search Begins at the first of the array and searches sequentially in order to find the target value. The array can be sorted or unsorted. On average the target value will be found in n/2 checks. Binary Search Begins at the middle of the array and checks for the target value, returning it if it is found. Otherwise, it excludes the half of the array the target can’t be in and goes to the midpoint of the half of the array it could be in. This continues until the target value is found or not found taking less than or equal to log2n + 1 checks. The array must be sorted. It is more efficient that Sequential Search for large arrays. It is a divide and conquer algorithm. Selection Sort On the first pass, swaps the smallest element into the first index location. On the second pass, swaps the next to smallest element into the second index location, etc. Makes only one swap per pass unless the smallest element for that pass is already in its correct final position. No particular worse case scenario. Insertion Sort Begins by placing the second element in order with the first element. On the second pass, places the third element in order with respect to the first two elements, and so on. Similar to placing cards in your hand in order while they are being dealt. Worse case scenario is when the array is in reverse order. Merge Sort It is a divide and conquer algorithm. It successively divides an array in half, keeping track of each half along the way until each part contains only one element. It then merges the half arrays back together with the elements in order. It is more efficient than Selection Sort or Insertion Sort. 56