-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathquick_sort.cpp
More file actions
72 lines (67 loc) · 1.82 KB
/
Copy pathquick_sort.cpp
File metadata and controls
72 lines (67 loc) · 1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/**
* @file quick_sort.cpp
* @brief
* @author Haoming Bai <haomingbai@hotmail.com>
* @date 2026-05-27
*
* Copyright © 2026 Haoming Bai
* SPDX-License-Identifier: MIT
*
* @details
*/
#include <functional>
#include <iterator>
#include <utility>
template <typename It, typename Cmp = std::less<
std::remove_cvref_t<decltype(*std::declval<It>())>>>
void QuickSort(It begin, It end, Cmp cmp = Cmp{}) {
if (begin == end) {
return;
}
It left = begin, right = std::prev(end);
if (left == right) {
return;
}
left = std::next(left);
const auto &pivot_value = *begin;
while (left != right) {
// First find the rightest position on the right
// where the value at this position is less than the pivot,
// which means that it should be moved to left.
while (right != left && !cmp(*right, pivot_value)) {
// not *right < pivot_value
// -> *right >= pivot_value
right = std::prev(right);
}
// *right < pivot_value
// Then find the leftest position on the left
// where the value at this position is greater than the pivot,
// which means that is should be moved to right.
while (left != right && !cmp(pivot_value, *left)) {
// not pivot_value < *left
// -> *left <= pivot_value
left = std::next(left);
}
// *left > pivot_value
if (left != right) {
std::swap(*left, *right);
}
}
It pivot_it = left;
if (cmp(pivot_value, *pivot_it)) {
pivot_it = std::prev(pivot_it);
}
std::swap(*begin, *pivot_it);
QuickSort(begin, pivot_it, cmp);
QuickSort(std::next(pivot_it), end, cmp);
}
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3, 4, 5};
QuickSort(v.begin(), v.end(), std::greater<int>{});
for (auto &&e : v) {
std::cout << e << ' ';
}
std::cout << '\n';
}