quicksort.cpp 2.2 KB

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