Lab 10 - Quicksort
(12/04/2021)
Description
"Quicksort is a sorting algorithm developed by Tony Hoare that, on average, makes O(n log n) comparisons to sort n items. It is also known as partition-exchange sort. In the worst case, it makes O(n^2) comparisons, though this behavior is rare. Quicksort is typically faster in practice than other O(n log n) algorithms. Additionally, quicksort's sequential and localized memory references work well with a cache. Quicksort can be implemented as an in-place partitioning algorithm."
Learning Outcomes
By completing the Quicksort Lab, you will be able to:
- Understand and explain the Quicksort Algorithm
- Use recursion to quickly sort data.
- Properly manage memory in arrays.
The Lab
Lab requirements:
- Your program should be able to successfully sort all the numbers in an array, using your partition function.
- Your partition function should return the correct pivot index of the subarray.
- You must use a dynamically-allocated array for this lab; no other data structures may be used.
- You are required to implement the given abstract interface class (QSInterface.)
The following summarizes the commands used in the Quicksort lab:
COMMAND | DESCRIPTION | OUTPUT |
---|---|---|
QuickSort <capacity> | Dynamically allocate a QuickSort array of size capacity. Set current number of elements (Size) to 0. | OK
Error |
AddToArray <data1> <data2>... | Add data element(s) to QuickSort array. Duplicates are allowed. Dynamically increase array size as needed (by doubling array capacity.) | OK
Error |
Capacity | Return the capacity of the QuickSort array. | size |
Clear | Remove all inserted elements from the QuickSort array. (Do not delete QuickSort array - capacity stays the same.) | OK |
Size | Return the number of elements currently in the QuickSort array. | elements |
Sort <left> <right> | Revised quickSort the elements in the QuickSort array from index <left> to index <right> (where <right> is one past last element) using median-of-3 and partition functions. | OK
Error |
SortAll | Revised quickSort all the elements in the QuickSort array using median-of-3 and partition functions. | OK
Error |
MedianOfThree <left> <right> | 1) Calculate the middle index (middle = (left + right)/2). 2) Bubble-sort the values at the left, middle, and right indices. 3) Output the index of the (<right> is one past last element.) |
Index of the pivot (middle index);
-1 if provided with invalid input |
Partition <left> <right> <pivot> | Using the revised pivot algorithm, partition the QuickSort array (<left>, <right> and <pivot> indexes) around the pivot value. Values smaller than or equal to the pivot should be placed to the left of the pivot while values larger than the pivot should be placed to the right of the pivot. (<right> is one past last element.) | Pivot's ending index,
-1 if provided with invalid input |
PrintArray | Print the contents of the QuickSort array as comma separated values (using a friend insertion (<<) operator and toString() function.) | Array values.
Empty |
BONUS: Stats | Output the number of comparisons and exchanges of array data used by the sort commands (SortAll and Sort <left> <right> - reset the counts for each sort command.) | Comparisons,Exchanges |
Steps to Success:
- Step 1 - Begin with a main function.
- As with all labs this semester, you will need to write your own main function.
- Use command line arguments for input and output files.
- Step 2 - Add your QuickSort class.
- The templated QuickSort class is derived from the abstract template interface class (QSInterface.)
- Your QuickSort class should contain a dynamically-allocated templated array. Before you focus too much on the actual sorting algorithm, make sure the logistics of the class work correctly. Focus on addToArray(), clear(), getSize(), and toString() member functions.
- Step 3 - Write your medianOfThree() function in the QuickSort class.
- The Median-of-Three function takes left and right indexes as parameters and then calculates the index in the middle of the indexes (rounding down if necessary).
- Sort the left, middle, and right numbers from smallest to largest in the array.
- Finally, return the index of the middle value. This will be your pivot value in the sortAll() function.
- Note that medianOfThree() is not used in your partition() function. The pivot value will be supplied by an input file Partition command.
- Step 4 - Write your partition() function in the QuickSort class.
- The partition() function should begin by swapping the leftmost element of the array with the pivot index element.
- Now, follow the revised pivot algorithm presented in the textbook (pg. 611) to partition the array such that all elements less than or equal to the pivot value are left of the pivot and all elements great than the pivot value are to the right of the pivot.
- The partition() function should return the new location of the pivot index.
- Step 5 - Write the sortAll() function, using your medianOfThree()
and partition() functions.
- Note that this function will be recursive. Most people use sortAll() as a recursive starter function that then call another function to do the sorting.
- To revised quicksort, first call your medianOfThree() function to sort the first, middle, and last elements and return the pivot index.
- Now, call your partition() function, using the index returned from medianOfThree() as the pivot index. This function will return a new pivot index where your array is split.
- Finally, recursively call your sort() function on the two halves of your array, with one half from the left to the pivot and the other half from the pivot to the right.
- Note: Reset exchange and comparison counters at the beginning of Sort and SortAll commands for the Bonus test.
Helps and Hints
Finding Memory Leaks.
Understanding VS_MEM_CHECK Output.(collapse)
- You can find helpful hints and explanations of the VS_MEM_CHECK macro here.
Understanding Valgrind Output.(collapse)
- You can find helpful hints and explanations of Valgrind output here.
Quicksort Criteria
Instructions for submitting your lab:
- Zip all your lab source files (.cpp, .hpp, .h) into one folder. DO NOT INCLUDE YOUR WHOLE PROJECT!
- Submit your zipped lab source using the "Labs" tab on the class website.
- Your submitted lab source will be compiled and executed using a lab gcc compiler.
- Both input and output files will be specified by command line arguments.
- An auto-grader will compare your output files with expected results and you will shortly receive an accumulative score.
- The auto-grade process may abort on the first error. If so, correct the error and try again.
- You may re-submit your zipped source as many times as you like.
Use the following input and resulting output files in testing the Quicksort lab:
Input File | Output File | |
Test #1 | lab10_in_01.txt | lab10_out_01.txt |
Test #2 | lab10_in_02.txt | lab10_out_02.txt |
Test #3 | lab10_in_03.txt | lab10_out_03.txt |
Test #4 | lab10_in_04.txt | lab10_out_04.txt |
Test #5 | lab10_in_05.txt | lab10_out_05.txt |
Test #6 | lab10_in_06.txt | lab10_out_06.txt |
Test #7 | lab10_in_07.txt | lab10_out_07.txt |
The auto-grader will be expecting to find in your output file the following sections:
Fail |
Pass |
||
---|---|---|---|
The lab source will be peer reviewed using the following rubric:
No |
Partial |
Yes
|
||
---|---|---|---|---|
Overall Rating |
Easy to follow, readable, organized, and
well commented. |
|||
***NOTE: Any attempt to circumvent any lab requirement (ie, hard coding output, using loops instead of iterators where required, modifying a class interface, etc.) will be reported by peer reviewers and result in a zero score for the lab. |