| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- // Quicksort
- //
- // Author: Rob Gysel
- // ECS60, UC Davis
- // Adapted from: Lysecky & Vahid "Data Structures Essentials", zyBooks
- #include "quicksort.h"
- int* QuickSort(std::vector<int>* numbers) {
- int comparisonCounter = 0;
- int memAccessCounter = 0;
- static int returnCounters[2];
- QuickSortRecurse(numbers, 0, numbers->size() - 1, &comparisonCounter, &memAccessCounter);
- returnCounters[0] = comparisonCounter;
- returnCounters[1] = memAccessCounter;
- return returnCounters;
- }
- void QuickSortRecurse(std::vector<int>* numbers, int i, int k, int *comparisonCounter, int *memAccessCounter) {
- int j = 0;
- /* Base case: If there are 1 or zero elements to sort,
- partition is already sorted */
- if (i >= k) {
- return;
- }
- /* Partition the data within the array. Value j returned
- from partitioning is location of last element in low partition. */
- j = Partition(numbers, i, k, comparisonCounter, memAccessCounter);
- /* Recursively sort low partition (i to j) and
- high partition (j + 1 to k) */
- QuickSortRecurse(numbers, i, j, comparisonCounter, memAccessCounter);
- QuickSortRecurse(numbers, j + 1, k, comparisonCounter, memAccessCounter);
- return;
- }
- int Partition(std::vector<int>* numbers, int i, int k, int *comparisonCounter, int *memAccessCounter) {
- int l = 0;
- int h = 0;
- int midpoint = 0;
- int pivot = 0;
- int temp = 0;
- bool done = false;
- /* Pick middle element as pivot */
- midpoint = i + (k - i) / 2;
- pivot = (*numbers)[midpoint];
- *memAccessCounter = *memAccessCounter + 1;
- l = i;
- h = k;
- while (!done) {
- /* Increment l while numbers[l] < pivot */
- while ((*numbers)[l] < pivot) {
- *comparisonCounter = *comparisonCounter + 1;
- *memAccessCounter = *memAccessCounter + 1;
- ++l;
- }
- // count the last loop's comparisons
- *comparisonCounter = *comparisonCounter + 1;
- *memAccessCounter = *memAccessCounter + 1;
- /* Decrement h while pivot < numbers[h] */
- while (pivot < (*numbers)[h]) {
- *comparisonCounter = *comparisonCounter + 1;
- *memAccessCounter = *memAccessCounter + 1;
- --h;
- }
- // count the last loop's comparisons
- *comparisonCounter = *comparisonCounter + 1;
- *memAccessCounter = *memAccessCounter + 1;
- /* If there are zero or one elements remaining,
- all numbers are partitioned. Return h */
- if (l >= h) {
- done = true;
- }
- else {
- /* Swap numbers[l] and numbers[h],
- update l and h */
- temp = (*numbers)[l];
- *memAccessCounter = *memAccessCounter + 1;
- (*numbers)[l] = (*numbers)[h];
- *memAccessCounter = *memAccessCounter + 2;
- (*numbers)[h] = temp;
- *memAccessCounter = *memAccessCounter + 1;
- ++l;
- --h;
- }
- }
- return h;
- }
|