CSCI 362: Divide and Conquer (and Combine) Algorithms
Handout
Grab the handout tarfile from Autolab. untar it like normal
tar xvf ...
Overview
You’ve been tasked with implementing a few divide, conquer, and combine algorithms! Some are also just useful utilities in solving more complex problems.
Algorithms
- [9pts]
median3
– determines the median-of-3 for a given range - [10pts]
merge
– merges two sorted ranges to a new location - [15pts]
partition
– partitions a range using a 3-way partition and a given pivot - [10pts]
nth_element
– determines the kth-order statistic of a given range - [10pts]
merge_sort
– performs merge sort on a range by calling your version ofmerge
. TIP: you will need to create an extra vector and copy the sorted vector back to the original iterator range - [10pts]
quick_sort
– performs quick sort on a range. should callmedian3
to find the pivot andpartition
to divide.
Note: when you call a function, please be sure to use its fully
qualified name from SortUtils
. For example,
nth_element
will call partition
. You will want
to say SortUtils::partition
rather than just
partition
.
Required Functions
namespace SortUtils
{
// Given a RandomAccessRange [first, last), determine where the "midpoint"
// would be and perform the following steps:
// order *first, *mid, *std::prev(last) in such a way such that
// *first <= *mid <= *std::prev(last)
//
// returns the median value
//
template<std::random_access_iterator Iter>
std::iter_value_t<Iter>
(Iter first, Iter last);
median3
// Takes two sorted ranges [first1, last1) and [first2, last2)
// and "merges" them by copying values into the iterator starting
// at "out". Uses operator< for comparing values
//
// Returns the iterator of one-past-the-last where we wrote to out
//
template<typename Iter1, typename Iter2, typename OIter>
OIter(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, OIter out);
merge
// Takes a RandomAccessRange [first, last) and partitions the data into
// three groups -- this should be accomplished in a SINGLE PASS Big-O: O(N)
//
// Group 1: all values in [first, last) < pivot
// Group 2: all values in [first, last) == pivot
// Group 3: all values in [first, last) > pivot
//
// [ ... Group 1 ... | ... Group 2 ... | ... Group 3 ... ]
// ^ ^
// p1 p2
//
// Returns a pair of iterators pointing to "p1" and "p2" above
//
template<typename Iter, typename Value>
std::pair<Iter, Iter>
(Iter first, Iter last, Value const& pivot);
partition
// Given a RandomAccessRange, recursively call partition on either the
// left half or right half until you have found the nth largest element
//
// A call to nth_element (v.begin(), v.end(), 0) will return the min
// A call to nth_element (v.begin(), v.end(), v.size() - 1) will return the max
// A call to nth_element (v.begin(), v.end(), v.size() / 2) will return the median
//
// Precondition:
// std::distance (begin, end) > n
//
// Hints:
// - n will change if you need to recurse on the right half
// - No recursion happens if "index of" n is between "index of" p1 and p2
// remember: p1 and p2 are the return values to partition.
// - call median3 to get a pivot value
//
template<typename Iter>
Iter(Iter first, Iter last, size_t n);
nth_element
// Given a RandomAccessRange, sort the range with merge_sort
//
// Behavior should be identical to std::sort
//
// Precondition:
// std::distance (begin, end) > n
//
// Hints:
// - You will need a local vector allocated to use as the "output" parameter for merge
//
template<typename Iter>
void
(Iter first, Iter last);
merge_sort
// Given a RandomAccessRange, sort the range with quick_sort
//
// Behavior should be identical to std::sort
//
// Precondition:
// std::distance (begin, end) > n
//
// Hints:
// - call median3 to get a pivot value
//
template<typename Iter>
void
(Iter first, Iter last);
quick_sort
} // end namespace SortUtils
Running the autograder
Invoking make
should create the autograder.
There can be a lot of output shown from the autograder. Some of it could be overwhelming at times. I recommend adding a couple of arguments to the autograder to help ease the pain.
./autograder -a
Will run the autograder and stop as soon as the first FAILURE is found
./autograder -t
Will list all of the tags for each of the tests. If you want to run a specific subset of tags you can do so by stating the following:
./autograder [access],[iterator]
Will run all tests that have the access and iterator tags
./autograder --failed
Will list all failed tests at the end of the autograder output
./autograder --passed
Will list all passed tests at the end of the autograder output
Style
Use good programming style:
- Write comments where appropriate
- Remember to include a comment block at the top of your program that
includes:
- Your name
- The course
- The last date of modification
- The assignment name
- A brief description of what your program does
- FORMAT YOUR CODE CONSISTENTLY
Submission
Please submit your header file to autolab
Grading
This lab is graded out of 75 points.
- [64pts] Unit tests
- [11pts] Style, Formatting, Comments
- NOTE: If your program does not compile/run, the
highest score you will earn will be a 11/75
- this means it is better to leave an implementation commented out if you can’t solve it