From c86f767cac6b6c0ffae2cdc76401946b81134ee1 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Mon, 11 Mar 2024 09:17:21 +0100 Subject: [PATCH] use median of five Median5 algorithm taken from: Fast Deterministic Selection by Andrei Alexandrescu - 2016 --- quick_select.hh | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/quick_select.hh b/quick_select.hh index d92f220..e27a5f0 100644 --- a/quick_select.hh +++ b/quick_select.hh @@ -19,22 +19,35 @@ static inline void swap(TYPE *a, int i, int j) } template -static inline void sort(TYPE *a, int i, int j, int k) +static inline void median(TYPE *A, int a, int b, int c, int d, int e) { - if (a[i] > a[j]) - swap(a, i, j); - if (a[i] > a[k]) - swap(a, i, k); - if (a[j] > a[k]) - swap(a, j, k); + if (A[c] < A[a]) + swap(A, a, c); + if (A[d] < A[b]) + swap(A, b, d); + if (A[d] < A[c]) { + swap(A, c, d); + swap(A, a, b); + } + if (A[e] < A[b]) + swap(A, b, e); + if (A[e] < A[c]) { + swap(A, c, e); + if (A[c] < A[a]) + swap(A, a, c); + } else if (A[c] < A[b]) { + swap(A, b, c); + } } template static void partition(TYPE *a, int &l, int &h) { - int m = l + (h - l) / 2; - sort(a, l, m, h); - TYPE pivot = a[m]; + int half = (h - l) / 2; + int quarter = (h - l) / 4; + int middle = l + half; + median(a, l, l + quarter, middle, middle + quarter, h); + TYPE pivot = a[middle]; for (int i = l; i <= h;) if (a[i] < pivot) swap(a, i++, l++);