void cut2(int N, int M) { // printf("cut2 %d %d \n", N, M); int L = M - N; if ( L < cut2Limit ) { quicksort0(N, M); return; } int depthLimit = 2 * floor(log(L)); cut2c(N, M, depthLimit); } // end cut2
// cut2 is used as a best in class quicksort implementation // with a defense against quadratic behavior due to duplicates // cut2 is a support function to call up the workhorse cut2c void cut2(void **A, int N, int M, int (*compare)()) { // printf("cut2 %d %d %d\n", N, M, M-N); int L = M - N; if ( L < cut2Limit ) { quicksort0(A, N, M, compare); return; } int depthLimit = 1 + 2.5 * floor(log(L)); cut2c(A, N, M, depthLimit, compare); } // end cut2
void cut2c(int N, int M, int depthLimit) { int L; Start: if ( depthLimit <= 0 ) { heapc(A, N, M); return; } L = M - N; if ( L < cut2Limit ) { quicksort0c(N, M, depthLimit); return; } depthLimit--; // Check for duplicates int sixth = (M - N + 1) / 6; int e1 = N + sixth; int e5 = M - sixth; int e3 = (N+M) / 2; // The midpoint int e4 = e3 + sixth; int e2 = e3 - sixth; // Sort these elements using a 5-element sorting network void *ae1 = A[e1], *ae2 = A[e2], *ae3 = A[e3], *ae4 = A[e4], *ae5 = A[e5]; void *t; // if (ae1 > ae2) { t = ae1; ae1 = ae2; ae2 = t; } if ( compareXY(ae1, ae2) > 0 ) { t = ae1; ae1 = ae2; ae2 = t; } if ( compareXY(ae4, ae5) > 0 ) { t = ae4; ae4 = ae5; ae5 = t; } if ( compareXY(ae1, ae3) > 0 ) { t = ae1; ae1 = ae3; ae3 = t; } if ( compareXY(ae2, ae3) > 0 ) { t = ae2; ae2 = ae3; ae3 = t; } if ( compareXY(ae1, ae4) > 0 ) { t = ae1; ae1 = ae4; ae4 = t; } if ( compareXY(ae3, ae4) > 0 ) { t = ae3; ae3 = ae4; ae4 = t; } if ( compareXY(ae2, ae5) > 0 ) { t = ae2; ae2 = ae5; ae5 = t; } if ( compareXY(ae2, ae3) > 0 ) { t = ae2; ae2 = ae3; ae3 = t; } if ( compareXY(ae4, ae5) > 0 ) { t = ae4; ae4 = ae5; ae5 = t; } A[e1] = ae1; A[e2] = ae2; A[e3] = ae3; A[e4] = ae4; A[e5] = ae5; // Fix end points if ( compareXY(ae1, A[N]) < 0 ) iswap(N, e1, A); if ( compareXY(A[M], ae5) < 0 ) iswap(M, e5, A); int duplicate = -1; // if ( ae1, ae5 ) { duplicate = e1; } else if ( compareXY(ae1, ae5) == 0 ) { duplicate = e1; } else if ( compareXY(ae1, ae4) == 0 ) { duplicate = e1; } else if ( compareXY(ae2, ae5) == 0 ) { duplicate = e2; } else if ( compareXY(ae1, ae3) == 0 ) { duplicate = e1; } else if ( compareXY(ae2, ae4) == 0 ) { duplicate = e2; } else if ( compareXY(ae3, ae5) == 0 ) { duplicate = e3; } else if ( compareXY(ae1, ae2) == 0 ) { duplicate = e1; } else if ( compareXY(ae2, ae3) == 0 ) { duplicate = e2; } else if ( compareXY(ae3, ae4) == 0 ) { duplicate = e3; } else if ( compareXY(ae4, ae5) == 0 ) { duplicate = e4; }; if ( 0 <= duplicate ) { void cut2c(); cut3duplicates(N, M, duplicate, cut2c, depthLimit); return; } register void *T = ae3; // pivot // test to play safe: // if ( T <= A[N] || A[M] < T ) { if ( compareXY(T, A[N]) <= 0 || compareXY(A[M], T) < 0 ) { // give up because cannot find a good pivot quicksort0c(N, M, depthLimit+1); return; } register int I, J; // indices register void *AI, *AJ; // array values // initialize running indices I= N; J= M; // The left segment has elements < T // The right segment has elements >= T Left: I = I + 1; AI = A[I]; // if (AI < T) goto Left; if ( compareXY( AI, T) < 0 ) goto Left; Right: J = J - 1; AJ = A[J]; // if ( T <= AJ ) goto Right; if ( compareXY( T, AJ) <= 0 ) goto Right; if ( I < J ) { A[I] = AJ; A[J] = AI; goto Left; } if ( (I - N) < (M - J) ) { // smallest one first cut2c(N, J, depthLimit); N = I; goto Start; } cut2c(I, M, depthLimit); M = J; goto Start; } // (* OF cut2; *) ... the brackets reminds that this was Pascal code