I've provided you with an IntelliJ project named sorters (as sorters.zip). In the Sorters.java class in this project, I implement most of the sorting methods of Bailey chapter 6, each declared within a class IntList which is my own implementation of an ArrayList<int>. One of the sort methods is isort(), which is an implementation of insertion sort taken straight from Bailey. There is also isort1().
You are to implement insertion sort outside of the IntList class, that is, in my SortTester.java file. Your function should take either an IntList and return an ArrayList<Integer> that represents a sorted copy of the original list. The original list is not to be modified. You are, instead, to use the ArrayList methods get() and add(). You will also use IntList.get(), to access the original list. For example, my version takes an IntList IL as parameter and has the following inner loop to find the position where value next = elements[k] is to be inserted into ArrayList<Integer> results, where k ranges over 0 to IL.size() in the outer loop:
while (i
>= 0 && results.get(i) > next) {
i --;
}
My code also includes the following to insert the value next into results. The two-parameter form of add() shifts everything from position i+1 to the end of the array up a slot.
results.add(i+1, next);
At the end, results is returned.
You can allocate all the space you will need in results with results.ensureCapacity(IL.size()). (This probably doesn't make much difference.)
How does the speed of your "external" insertion sort compare with the "internal" version?
Iterative mergesort works differently. At any one time, you visualize the array as a sequence of "blocks", each of size a perfect power of two except for the final block. At the start, the blocksize is 1, and each block of length 1 is, of course, sorted. The process repeats with successive block sizes 2, 4, 8, 16, 32, ... until the blocksize becomes larger than the entire array size. On an array of size 100 you would now do the following:
I've supplied you with the following merging methods:
T is the temp space, to be allocated at the start of imsort(). The first merger method, mergeblocks(), merges two equal-sized blocks; the second allows for the block sizes to be unequal. Use whichever you prefer. Both should handle having an undersized block as the last block of the array, but let me know if you have problems.
In class Sorters.java I've started the implementation of iterative mergesort in method imsort(). The code there is this:
public void
imsort() {
int[] temp = null; //
allocate temp; finish this!
int blockLength = 1;
while (blockLength <
elements.length) {
//mergepass(...)
//
swap elements and temp as follows:
//int
[] a = elements; // this is just a pointer, not an
allocation!
//elements = temp;
//temp = a;
blockLength *= 2;
}
}
You will have to edit this as necessary, and also edit the mergepass() code. You should not change the mergeblocks() methods. Make sure you allocate temp!
My class SortTester runs several versions of sorting algorithms on the same data, and records the time. Currently it runs InsertionSort, recursive MergeSort (Sorters.rmsort()), and Java's built-in Collections.sort(). You are to complete the definition of iterative mergesort, imsort(), and test it for speed against recursive mergesort and Collections.sort(). You will need to comment out the InsertionSort test once you've got imsort() working, as you'll need to test it with sizes much too large for InsertionSort to handle in a reasonable time.
We've already compared selection sort and insertion sort. You should:
Compare insertion sort with mergesort up to the point where insertion sort takes 10 seconds or more. Do enough measurements to convince yourself that insertion sort is O(n2), and that mergesort is not.
Next, compare the two mergesorts. Use block sizes of 1,000,000 up to 10,000,000 or so (doubling each time; say 1,000,000; 2,000,000; 5,000,000; 10,000,000), and tell me the relative times of iterative and recursive mergesort. You could add qsort2() if it works, or the built-in Java sort, but that's optional. Do the timing numbers seem consistent with O(n log(n))?Make sure you use checksort() to verify that your sort implementation works.
Submit your lab on Sakai.