Skip to content

Commit

Permalink
Halve the number of moves performed by poplar_sort
Browse files Browse the repository at this point in the history
Change its sift function to use cycles of moves instead of swaps.
  • Loading branch information
Morwenn committed Dec 27, 2023
1 parent b2916e5 commit 952ac0a
Showing 1 changed file with 32 additions and 19 deletions.
51 changes: 32 additions & 19 deletions include/cpp-sort/detail/poplar_sort.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2022 Morwenn
* Copyright (c) 2016-2023 Morwenn
* SPDX-License-Identifier: MIT
*/
#ifndef CPPSORT_DETAIL_POPLAR_SORT_H_
Expand Down Expand Up @@ -49,24 +49,37 @@ namespace cppsort::detail
auto child_root1 = root - 1;
auto child_root2 = first + (size / 2 - 1);

while (true) {
auto max_root = root;
if (comp(proj(*max_root), proj(*child_root1))) {
max_root = child_root1;
}
if (comp(proj(*max_root), proj(*child_root2))) {
max_root = child_root2;
}
if (max_root == root) return;

mstd::iter_swap(root, max_root);

size /= 2;
if (size < 2) return;

root = max_root;
child_root1 = root - 1;
child_root2 = max_root - (size - size / 2);
auto max_root = root;
if (comp(proj(*max_root), proj(*child_root1))) {
max_root = child_root1;
}
if (comp(proj(*max_root), proj(*child_root2))) {
max_root = child_root2;
}
if (max_root != root) {
auto value = mstd::iter_move(root);
auto&& value_proj = proj(value);
do {
*root = mstd::iter_move(max_root);

size /= 2;
if (size < 2) {
break;
};

root = max_root;
child_root1 = std::prev(root);
child_root2 = root - (size - size / 2);

auto max_child_it = child_root2;
if (comp(proj(*child_root2), proj(*child_root1))) {
max_child_it = child_root1;
}
if (comp(value_proj, proj(*max_child_it))) {
max_root = max_child_it;
}
} while (max_root != root);
*max_root = std::move(value);
}
}

Expand Down

0 comments on commit 952ac0a

Please sign in to comment.