#define SWAP(x,n) do {t=x[n];x[n]=x[n+1];x[n+1]=t;} while(0) #define SSWAP(x,n) do {if (x[n] > x[n+1]) SWAP(x,n);} while(0) /* nelt >= 3 */ static void median_to_front(int *base, int nelt) { int t; SSWAP(base,0); SSWAP(base,1); SSWAP(base,0); SWAP(base,0); /* cheap version -- not quite median value */ } /* 0 <= nelt < INT_MAX, base[0..nelt-1] valid */ void quicksort(int *base, int nelt) { int pivot, t, hi, lo; switch (nelt) { /* base cases */ case 2: SSWAP(base,0); /* fall through */ case 0: case 1: return; } /* 3 <= nelt */ median_to_front(base, nelt); pivot = base[0]; lo = 1; hi = nelt-1; /* lo < hi */ /* base[0..lo-1] <= pivot < base[hi+1..nelt-1] */ while (lo <= hi) { while (lo < nelt && base[lo] <= pivot) lo++; /* 0 <= lo == nelt || base[lo] > pivot */ while (0 <= hi && pivot < base[hi]) --hi; /* -1 == hi < nelt || base[hi] <= pivot */ if (lo < hi) { t = base[lo]; base[lo] = base[hi]; base[hi] = t; } } /* hi < lo */ /* base[0..lo-1] = base[0..hi] <= pivot < base[hi+1..nelt-1] * = base[lo..nelt-1] * 0 < lo = hi+1; lo=nelt possible if all entries identical */ /* t = base[0]; */ base[0] = base[lo-1]; base[lo-1] = pivot; /* lo-1 < nelt */ while (0 <= hi && base[hi] == pivot) hi--; /* hi < 0 || (0 < hi && base[hi] < pivot) */ if (0 < hi) quicksort(base,hi+1); if (lo < nelt) quicksort(base+lo,nelt-lo); /* nelt-1 - (hi+1) + 1 */ }