more efficient sort

master
Daniel Kolesa 2015-06-09 22:56:40 +01:00
parent ae68f1f379
commit 40b52ed765
1 changed files with 13 additions and 16 deletions

View File

@ -45,7 +45,7 @@ namespace detail {
octa::RangeSize<R> rlen = range.size(); octa::RangeSize<R> rlen = range.size();
for (octa::RangeSize<R> i = 1; i < rlen; ++i) { for (octa::RangeSize<R> i = 1; i < rlen; ++i) {
octa::RangeSize<R> j = i; octa::RangeSize<R> j = i;
octa::RangeReference<R> v = range[i]; octa::RangeValue<R> v = range[i];
while (j > 0 && !compare(range[j - 1], v)) { while (j > 0 && !compare(range[j - 1], v)) {
range[j] = range[j - 1]; range[j] = range[j - 1];
--j; --j;
@ -54,13 +54,6 @@ namespace detail {
} }
} }
template<typename T, typename U>
struct UnaryCompare {
const T &val;
U comp;
bool operator()(const T &v) const { return comp(v, val); }
};
template<typename R, typename C> template<typename R, typename C>
void hs_sift_down(R range, octa::RangeSize<R> s, void hs_sift_down(R range, octa::RangeSize<R> s,
octa::RangeSize<R> e, C compare) { octa::RangeSize<R> e, C compare) {
@ -105,14 +98,18 @@ namespace detail {
octa::detail::heapsort(range, compare); octa::detail::heapsort(range, compare);
return; return;
} }
octa::RangeReference<R> p = range[range.size() / 2]; octa::swap(range[range.size() / 2], range.back());
octa::swap(p, range.back()); octa::RangeSize<R> pi = 0;
R r = octa::partition(range, R pr = range;
octa::detail::UnaryCompare<decltype(p), C>{ p, compare }); pr.pop_back();
R l = range.slice(0, range.size() - r.size()); for (; !pr.empty(); pr.pop_front()) {
octa::swap(r.front(), r.back()); if (compare(pr.front(), range.back()))
octa::detail::introloop(l, compare, depth - 1); octa::swap(pr.front(), range[pi++]);
octa::detail::introloop(r, compare, depth - 1); }
octa::swap(range[pi], range.back());
octa::detail::introloop(range.slice(0, pi), compare, depth - 1);
octa::detail::introloop(range.slice(pi + 1, range.size()), compare,
depth - 1);
} }
template<typename R, typename C> template<typename R, typename C>