示例#1
0
int selectKth(int *num, int b, int e, int k)
{
	if (b >= e) {
		return num[b];
	}
	int cmpIndex = b + rand() % (e - b);
	swap(&num[cmpIndex], &num[e - 1]);
	int i, m = b - 1;
	for (i = b; i < e - 1; i++) {
		if (num[i] < num[e - 1]) {
			m++;
			swap(&num[i], &num[m]);
		}
	}
	m++;
	swap(&num[m], &num[e - 1]);
	i = m - b + 1;
	if (i == k) {
		return num[m];
	}
	else if(k < i) {
		selectKth(num, b, m, k);
	}
	else {
		selectKth(num, m + 1, e, k - i);
	}
}
/**
 * Average-case linear time recursive algorithm to find position of kth
 * element in ar, which is modified as this computation proceeds.  Note 1
 * <= k <= right-left+1.  The comparison function, cmp, is needed to
 * properly compare elements. Worst-case is quadratic, O(n^2).
 */
int selectKth (void **ar, int(*cmp)(const void *,const void *),
	       int k, int left, int right) {
  int idx = selectPivotIndex (ar, left, right);
  int pivotIndex = partition (ar, cmp, left, right, idx);
  if (left+k-1 == pivotIndex) { return pivotIndex; } 

  /* continue the loop, narrowing the range as appropriate. If we are within
   * the left-hand side of the pivot then k can stay the same. */
  if (left+k-1 < pivotIndex) {
    return selectKth (ar, cmp, k, left, pivotIndex - 1);
  } else {
    return selectKth (ar, cmp, k - (pivotIndex-left+1), pivotIndex+1, right);
  }
}
int main(int argc, char const *argv[])
{

  int k = atoi(argv[1]);
  int arr[] = {1,6,4,7,11,3,5,12};
            //{1,3,4,5,6,7,11,12}
  int n = sizeof(arr) / sizeof(arr[0]);
  std :: cout << n << std :: endl;
  std :: cout << selectKth(arr,k-1,n) << std :: endl;

  return 0;
}
示例#4
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    /* Matrix for input, temporary, and output. */
    double *Z, *ZTmp, v; // v return value, *Z input values.
    /* Size */
    mwSignedIndex n;
    /* k-th smallest element */
    int k;
    
    /* Check for proper number of arguments. */
    if ( nrhs != 2 ) {
        mexErrMsgIdAndTxt("MATLAB:imresize:rhs",
                "This function requires 2 input arguments.");
    }
    if ( nlhs != 1) {
        mexErrMsgIdAndTxt("MATLAB:imresize:lhs",
                "This function requires 1 output argument.");
    }
    
    k = (int) mxGetScalar(prhs[1]);
    n = (mwSignedIndex) mxGetM(prhs[0]);
    
    // Ensure that Z is a 1D column vector.
    if ( n < 1 || ((mwSignedIndex) mxGetN(prhs[0])) > 1 ) {
        mexErrMsgIdAndTxt("MATLAB:selectKth", "Z must be a 1D column-vector.");
    }
    // The index k must range have the range 1 <= k <= n.
    if ( k < 1 || k > n ) {
        mexErrMsgIdAndTxt("MATLAB:selectKth", "k must be >= 1 and <= n.");
    }
    
    Z = mxGetPr(prhs[0]);
    ZTmp = (double*) malloc(n * sizeof(double)); // Create copy because Z will be changed!
    memcpy(ZTmp, Z, n * sizeof(double));
    
    v = selectKth(ZTmp, n, k-1); // k-1 to match index range 0...n-1
        
    plhs[0] = mxCreateDoubleScalar(v);
    
    free(ZTmp);
}
/**
 * Sort using medianSort method.
 * 
 * @param ar           array of elements to be sorted.
 * @param cmp          comparison function to order elements.

 * @param left     The left-bounds within which to sort (0 <= left < ar.length)
 * @param right    The right-bounds within which to sort (0 <= right < ar.length)
 */
void mediansort (void **ar, int(*cmp)(const void *,const void *),
		 int left, int right) {
  int me, mid;

  /* if the subarray to be sorted has 1 (or fewer!) elements, done. */
  if (right <= left) { return; }
  
  /* get midpoint and median element position (note 1<=k<=right-left-1). */
  mid = (right - left + 1)/2; 
  me = selectKth (ar, cmp, mid+1, left, right);
  
  /* at this point, me should be equal to mid+1. */
  if (mid-1 <= minSize) {
    insertion (ar, cmp, left, left+mid-1);
  } else {
    mediansort (ar, cmp, left, left+mid-1);
  }

  if (right-left-mid-1 <= minSize) {
    insertion (ar, cmp, left+mid+1, right);
  } else {
    mediansort (ar, cmp, left+mid+1, right);
  }
}