CS 415, Section 002 | Sonoma State University | Spring, 2022 |
Algorithm Analysis
|
||
Instructor: Henry M. Walker
Lecturer, Sonoma State University |
This laboratory exercise applies the concept of loop invariants to problems involving array structures.
Several useful applications utilize a function
int partition (int a[], int left, int right)
This function rearranges the elements of a between a[left] and a[right], so that one array element has moved to the place it would belong in a sorted array. That is, the array elements are permuted to achieve the property described by the following array picture:
As suggested by this picture, partition moves an element of a to a position a[middle] and rearranges the remainder of the array segment a[left] ... a[right], so that
As it finishes, function partition returns the final value of middle.
Thus, the array segment a[left] ... a[right] is rearranged as required, to give a new arrangement of values a[left] ... a[(middle)] ... a[right], where all array elements before position middle have values <= a[(middle)] and where a[(middle)] is less than or equal to all array elements after position middle.
In its simplest form, the designated element within partition begins at a[left]. To accomplish the final arrangement shown above, we develop a loop that maintains the following picture:
To clarify this diagram, the variable r_spot gives the location, so that a[r_spot+1], ..., a[right] are all >= a[left], and a[left+1], ..., a[l_spot-1] are all <= a[left].
The main work in partition is to narrow the array segment in the middle of the above diagram, until there are no elements left in the middle. The main idea is to move r_spot to the left to find a small element and l_spot to the right to find a large element. Then we can swap the elements at positions l_spot and r_spot to expand the array segments for the small and large elements. Once the middle section has been eliminated, we swap a[left] and a[r_spot] to obtain the diagram at the beginning of this lab.
Adding some detail, partition proceeds with single pass through the elements a[left] ... a[right], as follow:
move left in the array through a[right], a[right-1], ... until finding an element a[r_spot] where a[r_spot] < a[left], if such an element exists.
move right in the array through a[left], a[left+1], ... until finding an element a[l_spot] where a[l_spot] > a[left], if such an element exists.
swap a[l_spot] and a[r_spot].
continue steps a, b, and c until searching all elements in the array segment. (At this point, "small" values will have been moved early within the array segment, while "large" values will have been moved late.)
place a[left] in its appropriate position a[middle], where middle is the index where l_spot and r_spot have come together.
The first work for this lab asks you to implement partition.
Use the in-progress diagram above to determine the exit condition for your loop, and explain why this condition is correct.
Write the partition code based on this diagram, and test it with several cases. In submiting the lab, include the partition code, the enclosing program used for testing, and a print out of the test cases/runs used to check correctness.
The partition method may be used to find the kth smallest element in an array involves narrowing the range to be examined within the overall array using the partition method. For example, suppose that partition returns index middle as the location of the final location for the pivot. Basic processing involves three cases:
If middle is k-1, that is, if middle is the kth element in the array, then the element at that position is the kth smallest.
If middle < k-1, then one should look for the k largest element in the subarray to the left of the index middle.
If middle > k-1, then one should look for the k largest element in the subarray to the right of the index middle.
Write a procedure select that uses the above algorithm and procedure partition to find the kth smallest element in an array a. Your lab write up should include the code for select, the enclosing program used for testing, and the test runs used for checking correctness.
Write a procedure median uses the above algorithm and procedures partition and/or select.to find the median element in an array. Your lab write up should include the code for median, the enclosing program used for testing, and the test runs used for checking correctness.
The quicksort algorithm proceeds by applying partition recursively, until all subintervals have no more than a single element (and thus are already sorted).
Write a quicksort procedure that uses the partition procedure and sorts the array a using the quicksort algorithm.
Include your quicksort procedure in an appropriate test program, so that you can adequately check the correctness of your code.
Programming Notes: As with the Select method, in practice, the procedure header for quicksort and some coding elements depend upon the programming language being utilized.
void quicksort (int a[], int n)
With this header, a recursive call for m elements on the left of the array would be
void quicksort (a, m)
Similarly, a recursive call for m elements, starting at a[j] would be either of the following:
void quicksort (a+j, m) //alternative a void quicksort (&a[j], m) //alternative b
void quicksort (int a[])With this header, one cannot directly call partition on a subarray, so from a programmer's perspective, one wants both a left and right parameter, just as in partition. To accomplish this, one approach utilizes a separate kernel that actually does the recursive quicksort:
void quicksortKernel (int a[], int left, int right)and the body of the quicksort just calls this behind-the-scenes method:
void quicksort (int a[]) { quicksortKernel (a, 0, a.length-1); }
The Dutch National Flag Problem was first proposed by W.H.J. Feijen and made famous by Edsger W. Dijkstra. The following formulation relates the problem to arrays in C.
Enumerations in C are described in Kernighan and Ritchie, Section 2.3, page 39. For example, an enumeration with three colors could be declared as:
enum color { red, white, blue };
and we may consider an array of colors:
#define size 50 /* number of elements in an array */ color colors [size];
When we begin, we do not know the number of elements of each color, and we are not even assured that each color is actually present.
The Dutch National Flag Problem seeks to sort this array, so that red's come first, then white's, and then blue's. Movement of array elements may be accomplished only by swapping two items.
Although one approach to this problem involves simple sorting (just consider red < white < blue), the problem can be solved in a single pass of the data. The idea is to identify an array diagram that describes sections of colors as loop invariants. Writing the code then is reasonably straightforward; we just have to maintain the invariant!
For this problem, at least four different pictorial loop invariants initially come to mind:
In each case, we must introduce variables to keep track of the edge of the red, white, and blue sections. Initially, these sections contain no elements, and the entire array is unprocessed. Then as processing proceeds, the program looks at successive unprocessed elements and puts them in their correct locations — maintaining the loop invariant.
For two of these pictorial loop invariants, introduce variables to record the index of a boundary between colors, and describe the invariant carefully in words. Then add the variables to the pictorial loop invariants. Check with your instructor before continuing!
In what follows you will create two loop segments to solve the Dutch National Flag Problem, one segment for each invariant you have identified above.
For each of the two approaches, initialize your variables, so that the pictorial loop invariants are satisfied at the start of processing.
Complete the loop processing, maintaining the identified loop invariant.
Test your program with several test runs.
created 20 April 2008 revised 24 January 2009 revised December-January 2021 |
|
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu. |