Skip to content

Commit 0475889

Browse files
committed
Improve code clarity in sort implementations
1 parent 240c3bf commit 0475889

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

c++/itertools/sort.hpp

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <functional>
2828
#include <iterator>
2929
#include <ranges>
30+
#include <utility>
3031

3132
namespace itertools {
3233

@@ -53,20 +54,22 @@ namespace itertools {
5354
* @param comp Comparison function callable with two dereferenced iterators.
5455
* @return Number of swaps necessary to sort the range.
5556
*/
56-
template <std::forward_iterator ForwardIt, class Compare = std::less<>>
57+
template <std::forward_iterator ForwardIt, typename Compare = std::less<>>
5758
std::size_t bubble_sort(ForwardIt first, ForwardIt last, Compare comp = {}) {
58-
if (first == last) { return 0; }
5959
std::size_t n_swaps = 0;
60-
for (ForwardIt sorted = first; first != last; last = sorted) {
61-
sorted = first;
62-
for (ForwardIt curr = first, prev = first; ++curr != last; ++prev) {
63-
if (comp(*curr, *prev)) {
64-
std::iter_swap(curr, prev);
65-
sorted = curr;
60+
61+
for (auto unsorted_end = last; first != unsorted_end;) {
62+
auto last_swap = first;
63+
for (auto curr = first, next = std::next(first); next != unsorted_end; ++curr, ++next) {
64+
if (comp(*next, *curr)) {
65+
std::iter_swap(next, curr);
66+
last_swap = next;
6667
++n_swaps;
6768
}
6869
}
70+
unsorted_end = last_swap; // Everything after last_swap is now in final position
6971
}
72+
7073
return n_swaps;
7174
}
7275

@@ -88,17 +91,22 @@ namespace itertools {
8891
* @param comp Comparison function callable with two dereferenced iterators.
8992
* @return Number of swaps necessary to sort the range.
9093
*/
91-
template <std::bidirectional_iterator BidirIt, class Compare = std::less<>>
94+
template <std::bidirectional_iterator BidirIt, typename Compare = std::less<>>
9295
std::size_t insertion_sort(BidirIt first, BidirIt last, Compare comp = {}) {
93-
if (first == last) { return 0; }
94-
std::size_t swaps = 0;
95-
for (BidirIt i = std::next(first); i != last; ++i) {
96-
for (BidirIt j = i; j != first && comp(*j, *std::prev(j)); --j) {
97-
std::iter_swap(std::prev(j), j);
98-
++swaps;
96+
if (first == last) return 0;
97+
98+
std::size_t n_swaps = 0;
99+
100+
for (auto unsorted_begin = std::next(first); unsorted_begin != last; ++unsorted_begin) {
101+
for (auto curr = unsorted_begin; curr != first; --curr) {
102+
auto prev = std::prev(curr);
103+
if (!comp(*curr, *prev)) break;
104+
std::iter_swap(prev, curr);
105+
++n_swaps;
99106
}
100107
}
101-
return swaps;
108+
109+
return n_swaps;
102110
}
103111

104112
/**
@@ -112,7 +120,7 @@ namespace itertools {
112120
* @param comp Comparison function callable with two dereferenced iterators.
113121
* @return Number of swaps necessary to sort the range.
114122
*/
115-
template <std::ranges::forward_range Range, class Compare = std::less<>>
123+
template <std::ranges::forward_range Range, typename Compare = std::less<>>
116124
std::size_t bubble_sort(Range &&rng, Compare comp = {}) { // NOLINT (ranges need not be forwarded)
117125
return bubble_sort(std::ranges::begin(rng), std::ranges::end(rng), comp);
118126
}
@@ -128,7 +136,7 @@ namespace itertools {
128136
* @param comp Comparison function callable with two dereferenced iterators.
129137
* @return Number of swaps necessary to sort the range.
130138
*/
131-
template <std::ranges::bidirectional_range Range, class Compare = std::less<>>
139+
template <std::ranges::bidirectional_range Range, typename Compare = std::less<>>
132140
std::size_t insertion_sort(Range &&rng, Compare comp = {}) { // NOLINT (ranges need not be forwarded)
133141
return insertion_sort(std::ranges::begin(rng), std::ranges::end(rng), comp);
134142
}

test/c++/itertools.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ TEST(Itertools, RangeRandomAccessOperations) {
371371
}
372372
}
373373

374-
// Create and fill a container of size n with random integers in [a,b].
374+
// Create and fill a container with random size in [0,n] with random integers in [a,b].
375375
template <typename C> auto random_int_range(std::size_t n, int a, int b) {
376376
static std::default_random_engine eng{std::random_device{}()};
377377
auto cont = C(std::uniform_int_distribution<std::size_t>(0, n)(eng));

0 commit comments

Comments
 (0)