The title is somewhat a misnomer; my apologies. The goal of the procedure is to partition a range of first, last
by mid
for the postcondition
max(first, mid) <= min(mid, last)
The actual code (best_n.h
):
#include <algorithm>
#include <iterator>
#if !defined(BidirectionalIterator)
#define BidirectionalIterator typename
#endif
template <BidirectionalIterator I>
void select_best(I first, I mid, I last) {
using T = typename I::value_type;
while (first != mid) {
T pivot = *first;
I pp = std::partition(first, last, [pivot](T elt) { return elt < pivot; });
if (pp == first) std::advance(pp, 1);
if (std::distance(first, pp) > std::distance(first, mid)) last = pp;
else first = pp;
}
}
Works fine if I didn't mistype anything.
Questions:
- Seeking overall improvements.
- What is a right name?
- Currently
void
. Is there anything useful to return? - I don't like passing lambda to
std::partition
. Any suggestions to avoid it? - A performance is weird. Regardless of a pivot selection strategy, an execution time stays pretty much constant as a function of
mid
. Obviously outperformsstd::partial_sort
for somewhat sizable initial ranges, but loses badly for short ones. Any suggestions?
PS: I have benchmarks if anybody's interested.
PPS: I am well aware of the beautiful best 2 Stepanov's approach. Challenging everybody to generalize it.
std::nth_element
instead ofstd::partial_sort
. \$\endgroup\$