The asker was specifically interested in a median-of-5 implementation based on sorting networks, so I will address this specific case. A brief review of the literature indicates what optimal solutions look like according to various metrics.
Michael Codish, Luís Cruz-Filipe, Thorsten Ehlers, Mike Müller, and Peter Schneider-Kamp. "Sorting networks: to the end and back again." Journal of Computer and System Sciences (2016) in table 1 shows that for n=5, the minimal number of compare-swaps is 9, and the minimal depth of the network is 5. As each compare-swap is equivalent to two min/max operations,
the minimal number of min/max operations required is 18.
Lukáŝ Sekanina, "Evolutionary Design Space Exploration for Median Circuits". In: EvoWorkshops, March 2004, pp. 240-249, gives the minimal number of min / max operations required for an optimal five-input median-selection network as 10 in table 1.
William Gasarch, Wayne Kelly, and William Pugh. "Finding the i th largest of n for small i, n." ACM SIGACT News 27, no. 2 (1996): 88-96, table 1:
at least 6 comparisons are needed for median-of-5.
In general, sorting networks with the minimal number of operations do not reduce to median-selection networks with the minimal number of operations simply by the elimination of redundant operations. But it is possible to find networks that do reduce in optimal fashion for at least some values of n. For n=5, a brute-force search for such networks is feasible.
The code below shows for four variants of five-input sorting networks comprising nine compare-swap operations or, alternatively, 18 min / max operations. When compiled with FULL_SORT = 0
these turn into median-selection networks with 10 min/max operations. So according to this metric, both sorting and median selection are optimal.
However, when used as a sorting network, all four variants have a depth of six instead of the minimum of five. Also, when configured as a median-selection network based on comparisons instead of min / max operations, all require seven rather than the minimum of six comparisons.
Example compilation results from Compiler Explorer (godbolt): Using 18 min / max operations for five-input sort, using 10 min / max operations for five-input median.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define VARIANT 1
#define USE_MIN_MAX 1
#define FULL_SORT 0
typedef float T;
#if USE_MIN_MAX
#define MIN(a,b) ((T)(fmin(a,b)))
#define MAX(a,b) ((T)(fmax(a,b)))
#define SWAP(i,j) do { T s = MIN(a##i,a##j); T t = MAX(a##i,a##j); a##i = s; a##j = t; } while (0)
#else // USE_MIN_MAX
#define MIN(a,b) (((a) > (b)) ? (b) : (a))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define SWAP(i,j) do { if (a##i > a##j) { T temp = a##i; a##i = a##j; a##j = temp; }} while (0)
#endif // USE_MIN_MAX
/* Use sorting/median network to fully or partially sort array of five values
and return the median value
*/
T network5 (T *a)
{
// copy to scalars
T a0, a1, a2, a3, a4;
a0=a[0];a1=a[1];a2=a[2];a3=a[3];a4=a[4];
#if VARIANT == 1
SWAP (0, 1); SWAP (2, 3);
SWAP (0, 2); SWAP (1, 3);
SWAP (2, 1);
SWAP (1, 4);
SWAP (1, 2);
SWAP (0, 1); SWAP (3, 4);
#elif VARIANT == 2
SWAP (3, 4); SWAP (0, 2);
SWAP (2, 4); SWAP (0, 3);
SWAP (2, 3);
SWAP (1, 2);
SWAP (0, 1); SWAP (2, 3);
SWAP (3, 4);
#elif VARIANT == 3
SWAP (3, 2); SWAP (0, 4);
SWAP (2, 4); SWAP (0, 3);
SWAP (2, 3);
SWAP (1, 2);
SWAP (0, 1); SWAP (2, 3);
SWAP (3, 4);
#elif VARIANT == 4
SWAP (2, 4); SWAP (0, 1);
SWAP (0, 2); SWAP (1, 4);
SWAP (2, 3);
SWAP (1, 2);
SWAP (2, 3); SWAP (0, 1);
SWAP (3, 4);
#else
#error unsupported VARIANT
#endif
#if FULL_SORT
// copy back sorted results
a[0]=a0;a[1]=a1;a[2]=a2;a[3]=a3;a[4]=a4;
#endif
// return median-of-5
return a2;
}
n
is small, a good implementation would be to use an array of pointers/indices and perform the swaps in the pointer array instead. – Headforemost