-
Notifications
You must be signed in to change notification settings - Fork 0
/
quicksort.hpp
70 lines (53 loc) · 1.48 KB
/
quicksort.hpp
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
// Copyright (c) Omar Boukli-Hacene. All rights reserved.
// Distributed under an MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT
/// Problem source:
/// https://en.wikipedia.org/wiki/Quicksort
#ifndef FORFUN_SORTING_QUICKSORT_HPP_
#define FORFUN_SORTING_QUICKSORT_HPP_
#include <algorithm>
#include <iterator>
namespace forfun::sorting {
template <std::contiguous_iterator Iter>
requires std::sortable<Iter>
constexpr auto quicksort(Iter first, Iter last) noexcept -> void;
namespace detail {
template <std::contiguous_iterator Iter>
[[nodiscard]] constexpr auto partition(Iter const first, Iter last) noexcept
-> Iter
{
auto it_i{first};
{
auto const pivot{*first};
for (auto it_j{--last}; it_j != it_i;)
{
if (*it_j < pivot)
{
std::iter_swap(++it_i, it_j);
}
else
{
--it_j;
}
}
}
std::iter_swap(first, it_i);
return it_i;
}
} // namespace detail
template <std::contiguous_iterator Iter>
requires std::sortable<Iter>
constexpr auto quicksort(Iter const first, Iter const last) noexcept -> void
{
using DiffType = std::iter_difference_t<Iter>;
if ((last - first) < DiffType{2})
{
return;
}
auto p{detail::partition(first, last)};
quicksort(first, p);
quicksort(++p, last);
}
} // namespace forfun::sorting
#endif // FORFUN_SORTING_QUICKSORT_HPP_