[Instructions] [Search] [Current] [Syllabus] [Links] [Handouts] [Outlines] [Labs] [More Labs] [Assignments] [Quizzes] [Examples] [Book] [Tutorial] [API]
Back to Sorting Algorithms. On to Sorting Lab.
Held Monday, March 1
Summary
Contents
Notes
/**
* Sort an array, creating a new sorted version 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.
*/
public Comparable[] mergeSort(Comparable[] A) {
return mergeSort(A[], 0, A.length-1);
} // mergeSort(Comparable[])
/**
* 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.
*/
public Comparable[] mergeSort(Comparable[] A, int lb, int ub) {
int middle; // Index of middle element
// 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) {
return copySubArray(A, lb, ub);
} // base case
// Recursive case: split and merge
else {
// Find the middle of the subarray.
middle = (lb + ub) / 2;
// Sort the two halves.
Comparable[] left = mergeSort(A, lb, middle);
Comparable[] right = mergeSort(A, middle+1, ub);
return merge(left, right);
} // recursive case
} // mergeSort(Comparable[], int, int)
/**
* 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 Comparable[] merge(Comparable[] left, Comparable[] right) {
// Create a new array of the appropriate size.
Comparable[] result = new Comparable[left.length + right.length];
// Create indices into the three arrays.
int left_index=0; // Index into left array.
int right_index=0; // Index into right array.
int index=0; // Index into result array.
// As long both vectors have elements, copy the smaller one.
while ((left_index < left.length) && (right_index < right.length)) {
if(left[left_index].lessThan(right[right_index])) {
result[index++] = left[left_index++];
} // first element in left subvector is smaller
else {
result[index++] = right[right_index++];
} // first element in right subvector is smaller
} // while both vectors have elements
// Copy any remaining parts of each vector.
while(left_index < left.length) {
result[index++] = left[left_index++];
} // while the left vector has elements
while(right_index < right.length) {
result[index++] = right[right_index++];
} // while the right vector has elements
// That's it
return result;
} // merge
/**
* 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(Comparable[] A) {
quickSort(A, 0, A.length-1);
} // quickSort(Comparable[])
/**
* Sort part of an array using Quicksort.
* Pre: All elements in the subarray can be compared to each other.
* Pre: 0 <= lb <= ub < A.length
* Post: The vector is sorted (using the standard meaning).
*/
public void quickSort(Comparable[] A, int lb, int ub) {
// Variables
Comparable 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(A,lb,ub);
// Determine the position of the pivot, while rearranging the array.
mid = partition(A, lb, ub);
// Recurse.
if (mid-1>=lb) quickSort(A, lb,mid-1);
if (mid+1<=ub) quickSort(A, mid+1,ub);
} // quickSort
/**
* 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(Comparable[] A, int lb, int ub) {
// Use the first element of the subsequence as the pivot value.
Comparable pivotval = A[lb];
int l=lb; // Elements [lb..l] are all <= pivotval
int r=ub; // Elements [r+1..ub] are all > pivotval
// Keep going until we run out of elements to put in the correct place.
while (l < r) {
// At this point, we know that
// (1) l < r
// (2) Elements [lb..l] are all <= pivotval
// (3) Elements [r+1..ub] are all > pivotval
// Skip over any large elements in the right half
while (pivotval.lessThan(A[r]) && (r > l)) {
--r;
}
// At this point, we know that
// (1) l <= r (we stop moving r left when we hit l or run out
// of large elements)
// (2) elements [lb..l] are all <= pivotval (we haven't moved l)
// (3) elements [r+1..ub] are all > pivotval (by the for loop)
// (4) element r is <= pivotval (we either stopped moving when
// we hit such an element or (a) r = l and (b) l indexes such
// an element)
// Skip over any small elements in the left half.
while ((A[l].lessEqual(pivotval)) && (l < r)) {
++l;
}
// At this point, we know that
// (1) l <= r (we stop moving r left when we hit l or
// possibly sooner; we stop moving l right when we hit
// r or possibly sooner)
// (2) elements [lb..l-1] are all <= pivotval (by the for loop)
// (3) elements [r+1..ub] are all > pivotval (we haven't moved r)
// (4) element r is <= pivotval (we either stopped moving when
// we hit such an element or r = l (and l indexes such an
// element)
// (5) if l < r then element l is > pivotval (by the for loop)
// (6) if l = r then element l is <= pivotval
// Do we have a large element in the left and a small element
// on the right?
if (A[l] > A[r]) {
swap(A,l,r);
}
} // while
// At this point, we know that
// (1) elements [lb..l] are all <= pivotval
// (2) elements [l+1..ub] are all > pivotval
// Put the pivot in the middle. Note that at this point, element l is
// <= pivotval, so this is a safe swap
swap(A,lb, l);
// And we're done
return l;
} // partition
History
Back to Sorting Algorithms. On to Sorting Lab.
[Instructions] [Search] [Current] [Syllabus] [Links] [Handouts] [Outlines] [Labs] [More Labs] [Assignments] [Quizzes] [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/99S/Outlines/outline.21.html
Source text last modified Sat Mar 13 18:05:30 1999.
This page generated on Sat Mar 13 18:13:38 1999 by SiteWeaver. Validate this page's HTML.
Contact our webmaster at rebelsky@math.grin.edu