Exemplo n.º 1
0
/* deadxc is also NOT used by FourSort.  It is employed for 
   a test to invoke cut3duplicates */
void deadxc(int N, int M, int depthLimit) {
  if ( depthLimit <= 0 ) {
    heapc(A, N, M);
    return;
  }
  int L = M - N;  
  if ( L < cut3Limit ) { 
    quicksort0c(N, M, depthLimit);
    return;
  }
  depthLimit--;

    int pivotx;
    int midpointx = (M+N)/2;
    if ( L <= 30 ) { // being defensive
      pivotx = med(A, N, midpointx, M, compareXY);
    } else {
      int step = L * 0.1;
      int P = med(A, N +   step, N + 2*step, N + 3*step, compareXY);
      int Q = med(A, midpointx - step, midpointx, midpointx + step, compareXY);
      int R = med(A, M - 3*step, M - 2*step, M - step, compareXY);
      pivotx = med(A, P, Q, R, compareXY);
    }

    void deadxc();
    cut3duplicates(N, M, pivotx, deadxc, depthLimit);
} // end deadxc
Exemplo n.º 2
0
// Cut2c does 2-partitioning with one pivot.
// Cut2c invokes dflgm when trouble is encountered.
void cut2c(void **A, int N, int M, int depthLimit, int (*compareXY)()) {
  int L;
 Start:
  L = M - N + 1;
  if ( L <= 1 ) return;

  // /*
  if ( L < 8 ) { // insertionsort
    insertionsort(A, N, M, compareXY);
    return;
  }
  //  */

  if ( depthLimit <= 0 ) {
    heapc(A, N, M, compareXY);
    return;
  }
  depthLimit--;

  // /*
  if ( L < cut2Limit ) { 
    // This alternative over esaping to quicksort0c reduced 1/2% comparions
    int middlex = N + (L>>1); // N + L/2;
    int p0 = middlex;
    if ( 7 < L ) {
      int pn = N;
      int pm = M;
      if ( 51 < L ) {	
	int d = (L-2)>>3; // L/8;
	pn = med(A, pn, pn + d, pn + 2 * d, compareXY);
	p0 = med(A, p0 - d, p0, p0 + d, compareXY);
	pm = med(A, pm - 2 * d, pm - d, pm, compareXY);
      }
Exemplo n.º 3
0
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
Exemplo n.º 4
0
// Quicksort equipped with a defense against quadratic explosion;
// calling heapsort if depthlimit exhausted
void quicksort0c(int N, int M, int depthLimit) {
  // printf("Enter quicksort0c N: %d M: %d %d\n", N, M, depthLimit);
  while ( N < M ) {
    int L = M - N;
    if ( L <= 10 ) {
      insertionsort(N, M);
      return;
    }
    if ( depthLimit <= 0 ) {
      heapc(A, N, M);
      return;
    }
    depthLimit--;
    // 10 < L
    // grab median of 3 or 9 to get a good pivot
    int pn = N;
    int pm = M;
    int p0 = (pn+pm)/2;
    if ( 40 < L ) { // do median of 9
      int d = L/8;
      pn = med(A, pn, pn + d, pn + 2 * d, compareXY);
      p0 = med(A, p0 - d, p0, p0 + d, compareXY);
      pm = med(A, pm - 2 * d, pm - d, pm, compareXY);
      /* Activation of the check for duplicates gives a slow down of 
	 1/4% on uniform input.  If you suspect that duplicates
	 causing quadratic deterioration are not caught higher-up by cut3
	 you may want to experiment with this check::::
      if ( L < 100 ) { // check for duplicates
	int duplicate = -1;
	if ( compareXY(A[pn], A[pm]) == 0 ) { duplicate = pn; } else
	if ( compareXY(A[pn], A[p0]) == 0 ) { duplicate = pn; } else
	if ( compareXY(A[pm], A[p0]) == 0 ) { duplicate = pm; };
	if ( 0 < duplicate ) {
	  void quicksort0();
	  cut3duplicates(N, M, duplicate, quicksort0, depthLimit);
	  return;
	}
      }
      */
    }
    p0 = med(A, pn, p0, pm, compareXY); // p0 is index to 'best' pivot ...
    iswap(N, p0, A); // ... and is put in first position as required by quicksort0c

    register void *p = A[N]; // pivot
    register int i, j;
    i = N;
    j = M;
    register void *ai; void *aj;

    /* Split array A[N,M], N<M in two segments using pivot p; 
       construct a partition with A[N,i), A(i,M] and N <= i <= M, and
       N <= k <= i -> A[k] <= p  and  i < k <= M -> p < A[k];
       Allow the worse cases: N=i or i=M.
       Recurse on A[N,i) and A(i,M) (or in the reverse order).
       This code does NOT do swapping; instead it disposes 
       ai/aj in a hole created by setting aj/ai first.  
    */
    /* Start state:
	  |-------------------------------|
          N=i                           j=M
	  N = i < j = M
          N <= k < i -> A[k] <= p    
          N < j < k <= M -> p < A[k]
	  A[N] = p
          N < i -> p < A[i]
    */
    while ( i < j ) {
      /*
	  |-------o---------------[--------|
          N       i               j        M
	  N <= i < j <= M
          N <= k < i -> A[k] <= p    
          N < j < k <= M -> p < A[k]
	  A[N] <= p
          N < i -> p < A[i]
          p + A[N,i) + A(i,M] is a permutation of the input array
      */
      aj = A[j];
      while ( compareXY(p, aj) < 0 ) { 
        /*
	  |-------o---------------[--------|
          N       i               j        M
	  N = i < j <= M or N < i <= j <= M
          N <= k < i -> A[k] <= p    
          N < j <= k <= M -> p < A[k]
	  A[N] <= p
	  N < i -> p < A[i}
	  p + A[N,i) + A(i,M] is a permutation of the input array
          p < aj = A[j]
	*/
	j--; 
	aj = A[j]; 
      }
      /*
	  |-------o---------------[--------|
          N       i               j        M
	  N = i = j < M or N < i & = i-1 <= j <= M
          N <= k < i -> A[k] <= p    
          j < k <= M -> p < A[k]
	  A[N] <= p
	  N < i -> p < A[i}
	  p + A[N,i) + A(i,M] is a permutation of the input array
          aj = A[j] <= p
	*/
      if ( j <= i ) {
	/*
	  |-------o-----------------------|
          N       i                       M
	  N = i = j < M or N < i & = i-1 = j < M
          N <= k < i -> A[k] <= p    
          i < k <= M -> p < A[k]
	  A[N] <= p
	  p + A[N,i) + A(i,M] is a permutation of the input array
      */
	break;
      }
      // i < j 
      A[i] = aj; // fill hole !
      /*
	  |-------]---------------o--------|
          N       i               j        M
	  N <= i < j <= M
          N <= k <= i -> A[k] <= p    
          j < k <= M -> p < A[k]
	  A[N] <= p
	  p + A[N,j) + A(j,M] is a permutation of the input array
	  aj = A[j] <= p
      */
      i++; ai = A[i];
      while ( i < j && compareXY(ai, p) <= 0 ) {
      /*
	  |-------]---------------o--------|
          N       i               j        M
	  N < i < j <= M
          N <= k <= i -> A[k] <= p    
          j < k <= M -> p < A[k]
	  A[N] <= p
	  p + A[N,j) + A(j,M] is a permutation of the input array
	  aj = A[j] <= p
      */
	i++; ai = A[i]; 
      }
      if ( j <= i ) 
      /*
	  |----------------------o--------|
          N                     i=j       M
	  N < i = j <= M
          N <= k < i -> A[k] <= p    
          j < k <= M -> p < A[k]
	  A[N] <= p
	  p + A[N,j) + A(j,M] is a permutation of the input array
      */
	break;
      // i < j  & p < ai = A[i] 
      A[j] = ai;
      j--;
      /*
	  |--------o--------------[--------|
          N        i              j        M
	  N < i <= j <= M
          N <= k < i -> A[k] <= p    
          j < k <= M -> p < A[k]
	  A[N] <= p
          N < i -> p < ai = A[i]
	  p + A[N,i) + A(i,M] is a permutation of the input array
      */
    }
    A[i] = p;
    /*
	  |--------]----------------------|
          N        i                      M
	  N <= i <= M
          N <= k <= i -> A[k] <= p    
          i < k <= M -> p < A[k]
	  A[N] <= p
	  A[N,i] + A(i,M] is a permutation of the input array
    */
    // Recurse on the smallest one and iterate on the other one
    int ia = i-1; int ib = i+1; 
    if ( i-N < M-i ) { 
      if ( N < ia ) quicksort0c(N, ia, depthLimit);  
      N = ib; 
    } else { 
      if ( ib < M ) quicksort0c(ib, M, depthLimit);  
      M = ia; 
    }
  }
} // end of quicksort0c