The goal of this assignment is to learn more about sorting and about object comparisons.
This assignment requires you to implement the three sorting algorithms discussed in class: selection sort, bubble sort, and insertion sort, and to compare them in terms of number of operations.
This assignment also has you practice writing a meaningful compare() method.
Sorting is the process of arranging data in a collection (usually an array) so that it is ordered, usually from smallest to largest or from first to last. For example, given an array that has the three strings "i", "c", and "s", sorting the array would place the three strings in the order "c", "i", and "s". An array with the numbers 3, 1, 4, 1, 5, 9, 2, 6, 5, 3 (the first 10 digits of pi) would be sorted to have the numbers in the order 1, 1, 2, 3, 3, 4, 5, 5, 6, 9.
Two out of the three sorting algorithms we have presented so far can be implemented with an underlying swap operation that swaps adjacent elements of an array. This operation is defined as:
/** * @param: the array within which to swap the two elements * @param: swap the elements at positions index and index + 1 * @throws: if index < 0 or index > data.length - 2 */ public static void swapAdjacent(E[] data, int index) throws java.lang.ArrayIndexOutOfBoundsException { E swap = data[index]; data[index] = data[index + 1]; data[index + 1] = swap; }
Note the unusual type notation E. This is a type parameter, and will be discussed in class once we start talking about collections. For this assignment, you should use it as you would any other type.
This algorithm is all about swapping adjacent elements if they are in the wrong order. You must create a method called reorder that swaps two adjacent elements, but only if they are not already in the right order.
The outer loop of bubble sort should stop once all elements are in the right order, that is, after an inner loop that has not reordered any elements. To implement this, reorder must return true if it has swapped its two elements, and false otherwise. If all the calls to reorder in an inner loop return false, then the outer loop must exit. Since the inner loop must be executed at least once, you must use a do { ... } while (); loop as the outer loop.
The inner loop of bubble must sort reorder all pairs of elements: first elements 0 and 1, then 1 and 2, then 2 and 3, and so on.
Swapping adjacent elements also lets us implement insertion sort. In the inner loop, the next unsorted element is compared with the element before it, and swapped if they are not in the correct order. This continues with elements at lower indices, until the element is in the correct position in the sorted part of the array.
You must reuse the method reorder from bubble sort. In insertion sort, the inner loop can stop as soon as reorder returns false. Unlike bubble sort, the outer loop executes a fixed number of times.
For example, if elements 0..7 of an array have already been sorted, then the inner loop of insertion sort reorders the elements at indices 7 and 8. If those are swapped (because they were not in the correct order), it reorders 6 and 7, then 5 and 6. The inner loop continues until it finds two elements that are already in the correct order, or until it has finished by swapping 0 and 1.
This is the one algorithm in this assignment that cannot be implemented using swapAdjacent. Instead, you must create a new method swapDistant which takes as parameters two indices instead of one index, and swaps the elements at the given positions of the array. You are encouraged to copy and modify the code from swapAdjacent in creating swapDistant.
In selection sort, the inner loop searches for the smallest element in the unsorted part of the array, and swaps that with the first unsorted element in the array. Because of this, you are encouraged to create a minIndex method that returns the index of the smallest element in array positions i..array.length - 1.
Using as example an an array initially containing c, f, d, a, e, the first execution of the inner loop your code finds that the element at index 3 is the smallest of all the elements in positions 0..4, so the outer loop swaps the element at index 3 with the element at index 0, giving a, f, d, c, e.
The second iteration of the outer loop find that the smallest element in positions 1..4 is again at index 3, so it swaps the element at index 3 with the element at index 1 to give a, c, d, f, e.
The third iteration of the outer loop find that the smallest element in 2..4 is at index 2, so it swaps the element at index 2 with the element at index 2, which does not change the array. Make sure your swapDistant method works correctly in this case.
The fourth iteration of the outer loop find that the smallest element in 3..4 is at index 4, so it swaps the element at index 4 with the element at index 3, giving a, c, d, e, f. The array is now sorted.
All your comparisons and swaps in the first two sorts should be in the reorder method. Modify the reorder method so it keeps counts of both the number of comparisons it does. The swapAdjacent method provided by the instructor in the Sort class already tracks the number of swaps.
For selection sort, minIndex has to keep track of the number of comparisons, and swapDistant should keep track of the number of swaps. For purposes of this assignment (and for simplicity), swapping two elements at the same index (as in the third iteration in the example above) still counts as a swap.
Your sort code must be in a Sort class. The instructor has provided a bare-bones Sort class which you should fill in with your code.
In addition, the instructor has provided a partial SortTest class and a complete StringComparator class.
Your task is to do all of the following:
The StringComparator has a main method which runs simple unit tests. You are strongly encouraged (but not required) to have similar unit tests.
Once you have created your IntegerComparator class, in SortTest uncomment lines 25,
private IntegerComparator ic;and 44,
ic = new IntegerComparator();
As part of this assignment, evaluate the big-O of selection sort and insertion sort. This analysis should be on the same level as the analysis for bubble sort on slide 10 of the September 12th presentation.
Include your analysis in a separate document, in either .txt or .pdf format. This part counts for 15% of the grade.
If you implement the correct algorithms, and they successfully sort, and you write a reasonable (as understood by the TA) testIntegerSorts, and your code passes all the tests, and your algorithm analysis is correct, you will get full credit.
As in any code that works with arrays, be careful of off-by-one errors. These are particularly likely in this assignment because we are dealing with pairs of adjacent elements, that is, indices such as i and i+1. Try as hard as you can to have a clear understanding of how each algorithm works, and to reflect that understanding in your code.
Be sure to review all your code at least once, adding comments where needed. Make sure each of your source files, including the JUnit test SortTest, has a proper file comment including your name and a description of what your code does.
As stated for previous homeworks, if you have time, it is usually helpful to have a substantial interval of time (hours to days) between when you complete your code, and when you do the final commenting and cleanup. Your comments will make more sense because you will be seeing the code with fresh eyes, and you might even spot and fix the occasional bug!
Once you are done, use the File menu in Eclipse to Export your code. Under General, choose ArchiveFile. On the next screen, find your src directory and turn them into Laulima directly, without zipping.
Use Laulima to turn in your files to the TA. Once you log into Laulima and select the ICS 211 site, on the left-hand side will be an assignments tab.