560 likes | 699 Views
Chapter 14 Searching and Sorting. Go. Go. Section 1 - Sequential or Linear Search Section 2 - Binary Search Section 3 - Selection Sort Section 4 - Insertion Sort Section 5 - Merge Sort. Go. Go. Go. 1. Searches and Sorts.
E N D
Chapter 14Searching and Sorting Go Go Section 1 - Sequential or Linear Search Section 2 - Binary Search Section 3 - Selection Sort Section 4 - Insertion Sort Section 5 - Merge Sort Go Go Go 1
Searches and Sorts There are two search algorithms and three sort algorithms that you need to know for the AP Exam: • SequentialSearch also called LinearSearch • BinarySearch • Selection Sort • Insertion Sort • Merge Sort We will discuss each and note some important facts about each one. 2
Sequential Search or Linear Search SequentialSearch also called LinearSearch 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. publicstaticint 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 checkscan be added to see how many checks are needed to find the target value. publicstaticint 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. publicstaticint 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: publicstaticint 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: publicstaticint 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: publicstaticint 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
Binary Search BinarySearch 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 remainder of the search process. 12
Binary Search Code publicstaticint 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; } elseif (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 halfduring 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) = 3checks 8 – 15 elements takes … log2(16) or log2(24) = 4checks 16 – 31 elements takes … log2(32) or log2(25) = 5checks 32 - 63 elements takes … log2(64) or log2(26) = 6checks 64 - 127 elements takes … log2(128) or log2(27) = 7checks 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 Code publicintbinarySearch (int[] arr, int target) { int pos = recurBinarySearch (arr, target, 0, arr.length - 1); return pos; } privateintrecurBinarySearch (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; elseif (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. Mathematicallylog2n 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
Selection Sort Selection Sort gets its name from the fact that during the first “pass”,the smallest element in the array is “selected” andswapped 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. 68 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. 6813 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. 681318 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 publicstaticvoid 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 publicstaticvoid 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 - intcompareTo (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 - intcompareTo (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(); 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); lexicographical indicates alphabetical order 29
Sect 6 - intcompareTo (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 - intcompareTo (String other) In this code, word1 is the receiver objectthis and word2 is other. String word1 = “a”; String word2 = “b”; 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(“b”) returns-1 based on the Unicode (ASCII) values for “a” and “b” … 97 - 98 = -1 Note that word1 is calling the method. 31
Sect 6 - intcompareTo (String other) In this code, word1 is the receiver objectthis 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 - intcompareTo (String other) In this code, word1 is the receiver objectthis 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 - intcompareTo (String other) In this code, word1 is the receiver objectthis 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 - intcompareTo (String other) In this code, word1 is the receiver objectthis 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 - intcompareTo (String other) In this code, word1 is the receiver objectthis 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 - intcompareTo (String other) In this code, word1 is the receiver objectthis 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 - intcompareTo (String other) In this code, word1 is the receiver objectthis 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 publicstaticvoid 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 publicstaticvoid 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 orn2. Actually for this version of Selection Sort, the outside for loop runsn - 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. and so on. 43
Insertion Sort Insertion Sort gets its name from the fact that during each “pass”,the element being sorted is being “inserted” intoits 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 publicstaticvoid 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 publicstaticvoid 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 orn2. Actually for this version of Insertion Sort, the outside for loop runsn - 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