AlgoPlus v0.1.0
Loading...
Searching...
No Matches
quick_sort.h
1#ifndef ALGOPLUS_QUICK_SORT_H
2#define ALGOPLUS_QUICK_SORT_H
3
4#include <algorithm> // For std::partition and std::swap
5#include <iterator> // For std::iterator_traits
6
17template <typename Iter> Iter median_of_three(Iter a, Iter b, Iter c) {
18 if (*a < *b) {
19 if (*b < *c)
20 return b;
21 else if (*a < *c)
22 return c;
23 else
24 return a;
25 } else {
26 if (*a < *c)
27 return a;
28 else if (*b < *c)
29 return c;
30 else
31 return b;
32 }
33}
34
47template <typename Iter> void quick_sort(Iter begin, Iter end) {
48 auto distance = std::distance(begin, end);
49 if (distance <= 1) {
50 return;
51 }
52
53 // choose the pivot as median of first, middle and last element
54 Iter mid = begin + distance / 2;
55 Iter pivot_pos = median_of_three(begin, mid, end - 1);
56 auto pivot = *pivot_pos;
57
58 // swap pivot to start
59 std::swap(*begin, *pivot_pos);
60
61 Iter middle1 =
62 std::partition(begin + 1, end, [pivot](const auto& elem) { return elem < pivot; });
63
64 Iter middle2 =
65 std::partition(middle1, end, [pivot](const auto& elem) { return !(pivot < elem); });
66
67 // swap pivot to its final place
68 std::swap(*begin, *(middle1 - 1));
69
70 // recursively apply quick_sort to partitions
71 quick_sort(begin, middle1 - 1);
72 quick_sort(middle2, end);
73}
74
75#endif // QUICK_SORT_H