[Instructions] [Search] [Current] [Syllabus] [Links] [Handouts] [Outlines] [Labs] [More Labs] [Assignments] [Quizzes] [Exams] [Examples] [Book] [Tutorial] [API]
Back to Sorting Algorithms. On to Project Discussion.
Held Friday, October 8, 1999
Overview
Today we continue our discussion of sorting by visiting some more efficient sorting algorithms that use divide and conquer as their underlying design strategy.
Notes
Array
)
Contents
Handouts
Summary
import SimpleOutput; /** * A collection of techniques for sorting an input array. * * @author Samuel A. Rebelsky * @version 1.0 of October 1999 */ public class MergeSorter { // +--------+-------------------------------------------------- // | Fields | // +--------+ /** The current indent level. Used when logging steps. */ String indent = ""; // +----------------+------------------------------------------ // | Public Methods | // +----------------+ /** * Sort an array, creating a new sorted version of the array. * If the SimpleOutput object is non-null, prints a simple log * of what's happening. * Pre: The elements in the array can be compared to each other. * Pre: There is sufficient memory to complete the creation of the * new array (and the other steps of the algorithm). * Post: Returns a sorted version of the array (where sorted is * defined carefully elsewhere). * Post: Does not affect the original array. */ public Object[] sort(Object[] stuff, Comparator compare, SimpleOutput observer) throws IncomparableException { return mergeSort(stuff, 0, stuff.length-1, compare, observer); } // sort(Object[]) // +----------------+------------------------------------------ // | Helper Methods | // +----------------+ /** * Sort part of an array, creating a new sorted version of the * part of the array. * Pre: The elements in the array can be compared to each other. * Pre: There is sufficient memory to complete the creation of the * new array (and the other steps of the algorithm). * Post: Returns a sorted version of the array (where sorted is * defined carefully elsewhere). * Post: Does not affect the original array. */ protected Object[] mergeSort(Object[] stuff, int lb, int ub, Comparator compare, SimpleOutput observer) throws IncomparableException { Object[] sorted; // The sorted version int middle; // Index of middle element // Print some basic information. if (observer != null) { observer.print(indent + "Sorting: "); printSubArray(stuff, lb, ub, observer); indent = indent + " "; } // Base case: vector of size 0 or 1. Make a fresh copy so that // it's safe to modify (and is the appropriate size. if (ub <= lb) { sorted = copySubArray(stuff, lb, ub); } // base case // Recursive case: split and merge else { // Find the middle of the subarray. middle = (lb + ub) / 2; // Sort the two halves. Object[] left = mergeSort(stuff, lb, middle, compare, observer); Object[] right = mergeSort(stuff, middle+1, ub, compare, observer); sorted = merge(left, right, compare); } // recursive case // Print information, if appropriate if (observer != null) { indent = indent.substring(2); observer.print(indent + "Sorted: "); printSubArray(sorted, 0, sorted.length-1, observer); } // That's it. return sorted; } // mergeSort(Object[], int, int, Comparator) /** * Merge two sorted arrays into a new single sorted array. * Pre: Both vectors are sorted. * Pre: Elements in both vectors may be compared to each other. * Pre: There is sufficient memory to allocate the new array. * Post: The returned array is sorted, and contains all the * elements of the two arrays (no more, no less). * Post: The two arguments are not changed */ public Object[] merge(Object[] left, Object[] right, Comparator compare) throws IncomparableException { // Create a new array of the appropriate size. Object[] result = new Object[left.length + right.length]; // Create indices into the three arrays. int leftIndex=0; // Index into left array. int rightIndex=0; // Index into right array. int index=0; // Index into result array. // As long both vectors have elements, copy the smaller one. while ((leftIndex < left.length) && (rightIndex < right.length)) { if(compare.lessThan(left[leftIndex],right[rightIndex])) { result[index++] = left[leftIndex++]; } // first element in left subvector is smaller else { result[index++] = right[rightIndex++]; } // first element in right subvector is smaller } // while both vectors have elements // Copy any remaining parts of each vector. while(leftIndex < left.length) { result[index++] = left[leftIndex++]; } // while the left vector has elements while(rightIndex < right.length) { result[index++] = right[rightIndex++]; } // while the right vector has elements // That's it return result; } // merge /** * Copy a subarray (so that we can return it without affecting it). * Pre: 0 <= lb <= ub < stuff.length * Post: Does not affect stuff. * Post: Returns a new array containing only stuff[lb] .. stuff[ub]. */ protected Object[] copySubArray(Object[] stuff, int lb, int ub) { // Create the new array. Object[] result = new Object[ub-lb+1]; for (int i = lb; i <= ub; i++) { result[i-lb] = stuff[i]; } return result; } // copySubArray /** * Print a subarray. * Pre: 0 <= lb <= ub < stuff.length * Post: Does not affect stuff. */ protected void printSubArray(Object[] stuff, int lb, int ub, SimpleOutput out) { // Print all but the last element followed by a comma for (int i = lb; i < ub; ++i) { out.print(stuff[i].toString() + ","); } // Print the last element out.println(stuff[ub]); } // printSubArray } // MergeSorter
import MergeSorter; import SimpleOutput; import StringComparator; /** * A simple test of selection sort. * * @author Samuel A. Rebelsky * @version 1.0 of September 1999 */ public class TestMergeSorter { public static void main(String[] args) throws Exception { SimpleOutput out = new SimpleOutput(); MergeSorter sorter = new MergeSorter(); Object[] sorted = sorter.sort(args, new StringComparator(), out); for (int i = 0; i < sorted.length; ++i) { out.println(i + ": " + sorted[i]); } // for } // main(String[]) } // class TestMergeSorter
Array
s of size k as the
same "level".
Array
s of size k.
Array
class)?
/** * Sort an array using Quicksort. * Pre: All elements in the array can be compared to each other. * Post: The vector is sorted (using the standard meaning). */ public void quickSort(Object[] stuff) { quickSort(stuff, 0, stuff.length-1); } // quickSort(Object[]) /** * Sort part of an array using Quicksort. * Pre: All elements in the subarray can be compared to each other. * Pre: 0 <= lb <= ub < stuff.length * Post: The vector is sorted (using the standard meaning). */ public void quickSort(Object[] stuff, int lb, int ub, Comparator compare) { // Variables Object pivot; // The pivot used to split the vector int mid; // The position of the pivot // Base case: size one arrays are sorted. if (lb == ub) return; // Pick a pivot and put it at the front of the array. putPivotAtFront(stuff,lb,ub); // Determine the position of the pivot, while rearranging the array. mid = partition(stuff, lb, ub); // Recurse on nonempty subarrays. if (lb<=mid-1) quickSort(stuff, lb,mid-1); if (mid+1<=ub) quickSort(stuff, mid+1,ub); } // quickSrt /** * Split the array given by [lb .. ub] into ``smaller'' and * ``larger'' elements, where smaller and larger are defined by * their relationship to a pivot. Return the index of the pivot * between those elements. Uses the first element of the array * as the pivot. */ public int partition(Object[] stuff, int lb, int ub) { // STUB. Can you figure it out? return 0; } // partition(Object[])
Set pivot to the first element of the subarray Set left to the start of the subarray Set right to the end of the subarray Move left and right toward each other, Swap their contents when you observe that one side is "wrong" (something on the left is larger than the pivot, something on the right is larger than the pivot)
Tuesday, 10 August 1999
Wednesday, 6 October 1999
Thursday, 7 October 1999
Friday, 8 October 1999
Back to Sorting Algorithms. On to Project Discussion.
[Instructions] [Search] [Current] [Syllabus] [Links] [Handouts] [Outlines] [Labs] [More Labs] [Assignments] [Quizzes] [Exams] [Examples] [Book] [Tutorial] [API]
Disclaimer Often, these pages were created "on the fly" with little, if any, proofreading. Any or all of the information on the pages may be incorrect. Please contact me if you notice errors.
This page may be found at http://www.math.grin.edu/~rebelsky/Courses/CS152/99F/Outlines/outline.26.html
Source text last modified Fri Oct 8 08:58:26 1999.
This page generated on Fri Oct 8 08:58:52 1999 by Siteweaver. Validate this page's HTML.
Contact our webmaster at rebelsky@grinnell.edu