From 40b52ed76591a51bdf1179e592a501b4f725c6b7 Mon Sep 17 00:00:00 2001 From: q66 Date: Tue, 9 Jun 2015 22:56:40 +0100 Subject: [PATCH] more efficient sort --- octa/algorithm.h | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/octa/algorithm.h b/octa/algorithm.h index 25215e3..3688b5a 100644 --- a/octa/algorithm.h +++ b/octa/algorithm.h @@ -45,7 +45,7 @@ namespace detail { octa::RangeSize rlen = range.size(); for (octa::RangeSize i = 1; i < rlen; ++i) { octa::RangeSize j = i; - octa::RangeReference v = range[i]; + octa::RangeValue v = range[i]; while (j > 0 && !compare(range[j - 1], v)) { range[j] = range[j - 1]; --j; @@ -54,13 +54,6 @@ namespace detail { } } - template - struct UnaryCompare { - const T &val; - U comp; - bool operator()(const T &v) const { return comp(v, val); } - }; - template void hs_sift_down(R range, octa::RangeSize s, octa::RangeSize e, C compare) { @@ -105,14 +98,18 @@ namespace detail { octa::detail::heapsort(range, compare); return; } - octa::RangeReference p = range[range.size() / 2]; - octa::swap(p, range.back()); - R r = octa::partition(range, - octa::detail::UnaryCompare{ p, compare }); - R l = range.slice(0, range.size() - r.size()); - octa::swap(r.front(), r.back()); - octa::detail::introloop(l, compare, depth - 1); - octa::detail::introloop(r, compare, depth - 1); + octa::swap(range[range.size() / 2], range.back()); + octa::RangeSize pi = 0; + R pr = range; + pr.pop_back(); + for (; !pr.empty(); pr.pop_front()) { + if (compare(pr.front(), range.back())) + octa::swap(pr.front(), range[pi++]); + } + 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