quicksort.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Quicksort
  2. //
  3. // Author: Rob Gysel
  4. // ECS60, UC Davis
  5. // Adapted from: Lysecky & Vahid "Data Structures Essentials", zyBooks
  6. #include "quicksort.h"
  7. int* QuickSort(std::vector<int>* numbers) {
  8. int comparisonCounter = 0;
  9. int memAccessCounter = 0;
  10. static int returnCounters[2];
  11. QuickSortRecurse(numbers, 0, numbers->size() - 1, &comparisonCounter, &memAccessCounter);
  12. returnCounters[0] = comparisonCounter;
  13. returnCounters[1] = memAccessCounter;
  14. return returnCounters;
  15. }
  16. void QuickSortRecurse(std::vector<int>* numbers, int i, int k, int *comparisonCounter, int *memAccessCounter) {
  17. int j = 0;
  18. /* Base case: If there are 1 or zero elements to sort,
  19. partition is already sorted */
  20. if (i >= k) {
  21. return;
  22. }
  23. /* Partition the data within the array. Value j returned
  24. from partitioning is location of last element in low partition. */
  25. j = Partition(numbers, i, k, comparisonCounter, memAccessCounter);
  26. /* Recursively sort low partition (i to j) and
  27. high partition (j + 1 to k) */
  28. QuickSortRecurse(numbers, i, j, comparisonCounter, memAccessCounter);
  29. QuickSortRecurse(numbers, j + 1, k, comparisonCounter, memAccessCounter);
  30. return;
  31. }
  32. int Partition(std::vector<int>* numbers, int i, int k, int *comparisonCounter, int *memAccessCounter) {
  33. int l = 0;
  34. int h = 0;
  35. int midpoint = 0;
  36. int pivot = 0;
  37. int temp = 0;
  38. bool done = false;
  39. /* Pick middle element as pivot */
  40. midpoint = i + (k - i) / 2;
  41. pivot = (*numbers)[midpoint];
  42. *memAccessCounter = *memAccessCounter + 1;
  43. l = i;
  44. h = k;
  45. while (!done) {
  46. /* Increment l while numbers[l] < pivot */
  47. while ((*numbers)[l] < pivot) {
  48. *comparisonCounter = *comparisonCounter + 1;
  49. *memAccessCounter = *memAccessCounter + 1;
  50. ++l;
  51. }
  52. /* Decrement h while pivot < numbers[h] */
  53. while (pivot < (*numbers)[h]) {
  54. *comparisonCounter = *comparisonCounter + 1;
  55. *memAccessCounter = *memAccessCounter + 1;
  56. --h;
  57. }
  58. /* If there are zero or one elements remaining,
  59. all numbers are partitioned. Return h */
  60. if (l >= h) {
  61. done = true;
  62. }
  63. else {
  64. /* Swap numbers[l] and numbers[h],
  65. update l and h */
  66. temp = (*numbers)[l];
  67. *memAccessCounter = *memAccessCounter + 1;
  68. (*numbers)[l] = (*numbers)[h];
  69. *memAccessCounter = *memAccessCounter + 2;
  70. (*numbers)[h] = temp;
  71. *memAccessCounter = *memAccessCounter + 1;
  72. ++l;
  73. --h;
  74. }
  75. }
  76. return h;
  77. }