-rw-r--r-- 1464 djbsort-20180710/int32/portable2/sort.c
#include "int32_sort.h" #define int32 int32_t static inline int32 minmax(int32 a,int32 *y) { int32 b = *y; int32 ab = b ^ a; int32 c = b - a; c ^= ab & (c ^ b); c >>= 31; c &= ab; a ^= c; *y = b ^ c; return a; } /* precondition: n >= 2 */ /* precondition: m = ceil(n/2) */ /* inputs: x[0],...,x[n-1] */ /* outputs: x[0],x[m],x[1],x[m+1],... */ static void outshuffle(int32 *x,long long n,long long m) { int32 y[m]; long long j; for (j = 0;j < m;++j) y[j] = x[j]; for (j = m;j < n;++j) x[(j - m) * 2 + 1] = x[j]; for (j = 0;j < m;++j) x[j * 2] = y[j]; } /* precondition: n >= 2 */ /* precondition: m = ceil(n/2) */ /* precondition: x[0]...x[m-1] are in order */ /* precondition: x[m]...x[n-1] are in order */ /* postcondition: x[0]...x[n-1] are in order */ /* (and are same multiset as original inputs) */ static void merge(int32 *x,long long n,long long m) { long long q = 1; long long p; int32 *xj; int32 *y; y = x + n - m; for (xj = x;xj != y;++xj) *xj = minmax(*xj,xj + m); xj = x; while (q < m) q <<= 1; while (q >>= 1) { y = x + m - q; for (;xj != y;++xj) { int32 a = xj[m]; p = q; do a = minmax(a,xj + p); while (p >>= 1); xj[m] = a; } } outshuffle(x,n,m); } void int32_sort(int32 *x,long long n) { long long m; if (n < 2) return; m = (n + 1) >> 1; /* assumes n below 2^63-1 */ int32_sort(x,m); int32_sort(x + m,n - m); merge(x,n,m); }