예제 #1
0
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
예제 #2
0
파일: C2sort.c 프로젝트: ddccc/foursort
// 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
예제 #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