/** * Clayton Cafiero * CS 2240 * 05-Jan-2021 */ #include #include #include #include template void printVector(const std::vector& v) { for (Comparable item : v) { std::cout << item << " "; } std::cout << std::endl; } template int partition(std::vector& v, int start, int end) { Comparable pivot = v[end]; int i = start; for (int j = start; j <= end; ++j) { if (v[j] < pivot) { // swap v[i] and v[j] Comparable temp = v[j]; v[j] = v[i]; v[i] = temp; ++i; } } // swap v[i] and v[end] Comparable temp = v[i]; v[i] = v[end]; v[end] = temp; return i; } /** * Using median-of-three method of choosing a pivot */ template int partitionMedian3(std::vector& v, int start, int end) { int middle = (start + end) / 2; if (v[middle] < v[start]) { // swap middle and start Comparable temp = v[start]; v[start] = v[middle]; v[middle] = temp; } if (v[end] < v[start]) { // swap end and start Comparable temp = v[start]; v[start] = v[end]; v[end] = temp; } if (v[middle] < v[end]) { // swap middle and end Comparable temp = v[middle]; v[middle] = v[end]; v[end] = temp; } // the above leave the median of three at the end Comparable pivot = v[end]; int i = start; for (int j = start; j <= end; ++j) { if (v[j] < pivot) { // swap v[i] and v[j] Comparable temp = v[j]; v[j] = v[i]; v[i] = temp; ++i; } } // swap v[i] and v[end] Comparable temp = v[i]; v[i] = v[end]; v[end] = temp; return i; } /** * Quicksort */ template void quicksort(std::vector& v, int start, int end) { if (end <= start) { return; // base case of our recursion } else { // recursive case int p = partition(v, start, end); quicksort(v, start, p - 1); quicksort(v, p + 1, end); } } /** * Quicksort */ template void quicksortMedian3(std::vector& v, int start, int end) { if (end <= start) { return; // base case for recursion; single element } else { // recursive case int p = partitionMedian3(v, start, end); quicksortMedian3(v, start, p - 1); quicksortMedian3(v, p + 1, end); } } /** * Quicksort. This is to set up the first recursive call. */ template void quicksort(std::vector& v) { quicksort(v, 0, v.size() - 1); } template void quicksortMedian3(std::vector& v) { quicksortMedian3(v, 0, v.size() - 1); } int main() { std::random_device rd; std::vector baseVector; for (int i = 0; i < 10000; ++i) { baseVector.push_back(i); } std::shuffle(baseVector.begin(), baseVector.end(), rd); std::vector temp(baseVector.size()); std::cout << "Shuffled vector" << std::endl; std::vector v = baseVector; auto startTime = std::chrono::high_resolution_clock::now(); quicksort(v); auto endTime = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast (endTime - startTime).count(); std::cout << "Quicksort: " << duration << std::endl; v = baseVector; startTime = std::chrono::high_resolution_clock::now(); quicksortMedian3(v); endTime = std::chrono::high_resolution_clock::now(); duration = std::chrono::duration_cast (endTime - startTime).count(); std::cout << "Quicksort median-of-three: " << duration << std::endl; std::cout << std::endl; baseVector.clear(); for (int i = 0; i < 10000; ++i) { baseVector.push_back(i); } std::cout << "Sorted vector" << std::endl; v = baseVector; startTime = std::chrono::high_resolution_clock::now(); quicksort(v); endTime = std::chrono::high_resolution_clock::now(); duration = std::chrono::duration_cast (endTime - startTime).count(); std::cout << "Quicksort: " << duration << std::endl; v = baseVector; startTime = std::chrono::high_resolution_clock::now(); quicksortMedian3(v); endTime = std::chrono::high_resolution_clock::now(); duration = std::chrono::duration_cast (endTime - startTime).count(); std::cout << "Quicksort median-of-three: " << duration << std::endl; }