Please review the following implementation of heapsort and pay attention to the following:
- Have I correctly chosen the names
InputIt
andBidirIt
for my iterators? - Is there a way to make the
initialise iterator and then advance it
pattern occupy one line instead of two? - Is the
it != ix - 1
comparison of iterators ok?
Here is the code:
#include <iterator>
#include <functional>
template<
class InputIt,
class Key = std::less_equal<
std::iterator_traits<InputIt>::value_type
>
>
void plunge(
const InputIt ix, // first element of heap
const InputIt iy, // one-past last element of heap
const InputIt iz, // element to be plunged
Key key = Key() // comparison key to use (up or down)
) {
auto ii = iz;
auto il = ix;
std::advance(il, 2 * std::distance(ix, ii) + 1);
while (il < iy) {
auto ir = il + 1;
auto it = ir < iy && key(*ir, *il) ? ir : il;
if (key(*ii, *it)) {return;}
std::iter_swap(ii, it);
std:: swap(ii, it);
il = ix;
std::advance(il, 2 * std::distance(ix, ii) + 1);
}
}
template<
typename BidirIt,
typename Key = std::greater_equal<
std::iterator_traits<BidirIt>::value_type
>
>
void heapsort(const BidirIt ix, const BidirIt iy, Key key = Key()) {
auto it = ix;
std::advance(it, std::distance(ix, iy) / 2);
for (; it != ix - 1; --it) {
plunge(ix, iy, it, key);
}
for (it = iy - 1; it != ix - 1; --it) {
std::iter_swap(ix, it);
plunge(ix, it, ix, key);
}
}
std::sort_heap
. \$\endgroup\$std::next()
for turning initialize-then-advance into one line. \$\endgroup\$