/**
 * Sort array ar[left,right] using Quicksort method.
 */
void do_qsort (void *const pbase, size_t n, size_t s, 
	       int(*cmp)(const void *,const void *)) {
  void *pp;
  long ct, num;

  if (n <= 1) { return; }
  
  /* locate median (also placeds it in pbase[n-1]. */
  selectPivotIndex(pbase,n,s,cmp);
  pp = partition (pbase,n,s,cmp);
  
  ct = (long)pp - (long)pbase;
  num = ct / s;
  if (ct > minSize*s && ct > s) {
    do_qsort (pbase, num, s, cmp);
  } else if (ct > 1) {
    insertion (pbase, num, s, cmp);
  }

  ct = (long)pbase + (n-1)*s - (long)pp;
  num = ct / s;
  if (ct > minSize*s && ct > s) {
    do_qsort (pp+s, num, s, cmp);
  } else if (ct > 1) {
    insertion (pp+s, num, s, cmp);
  }

}
/**
 * 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);
  }
}
Пример #3
0
int Sort::findKthGreatestValue(std::vector<int> &vector, int k, int leftIndex, int rightIndex)
{
    assert(leftIndex >= 0 && leftIndex <= rightIndex && "Invalid left index.");
    assert(rightIndex < vector.size() && "Invalid right index.");
    assert(k > 0 && k <= rightIndex - leftIndex + 1 && "Invalid kth value.");
    
    int initialPivotIndex = selectPivotIndex(vector, leftIndex, rightIndex);
    
    // Partition the vector V so that the range V[leftIndex, finalPivotIndex) contains
    // only values <= the pivot value, and V(finalPivotIndex, rightIndex] contains only
    // values >= the pivot value.
    //
    int finalPivotIndex = partition(vector, leftIndex, rightIndex, initialPivotIndex);
    
    // Note that when the above completes, the value at the finalPivotIndex must be
    // the [(finalIndex + 1) - leftIndex]-th greatest value in the *range.*
    // (This is easiest to see in the case where leftIndex = 0).
    int orderOfPivotValue = (finalPivotIndex + 1) - leftIndex;
    
    // If we have found the kth greatest value in the range, then we are done.
    if (orderOfPivotValue == k) {
        return vector[finalPivotIndex];
    }
    
    // Otherwise, continue looking for the kth greatest value, narrowing the range
    // either to what comes before the finalPivotIndex, or what comes after.
    if (orderOfPivotValue > k)
    {
        // If we found the nth greatest value where n > k, then we can search to
        // the left of the nth value and leave k the same.
        return findKthGreatestValue(vector, k, leftIndex, finalPivotIndex - 1);
    }
    else
    {
        // If we found the nth greatest value where n < k, then we need to search
        // to the right of k.
        //
        // Note that now, we want to find the [k - orderOfPivotValue]-th greatest
        // value in the remaining range:
        return findKthGreatestValue(vector, k - orderOfPivotValue, finalPivotIndex + 1, rightIndex);
    }
}
Пример #4
0
/**
 * Sort array ar[left,right] using Quicksort method.
 * The comparison function, cmp, is needed to properly compare elements.
 */
void do_qsort (void **ar, int(*cmp)(const void *,const void *),
	       int left, int right) {
  int pivotIndex;
  if (right <= left) { return; }
  
  /* partition */
  pivotIndex = selectPivotIndex (ar, left, right);
  pivotIndex = partition (ar, cmp, left, right, pivotIndex);
  
  if (pivotIndex-1-left <= minSize) {
    insertion (ar, cmp, left, pivotIndex-1);
  } else {
    do_qsort (ar, cmp, left, pivotIndex-1);
  }
  if (right-pivotIndex-1 <= minSize) {
    insertion (ar, cmp, pivotIndex+1, right);
  } else {
    do_qsort (ar, cmp, pivotIndex+1, right);
  }
}
Пример #5
0
/**
 * Average-case linear time 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.
 *
 * @param ar           array of elements to be sorted.
 * @param cmp          comparison function to order elements.
 * @param k            kth smallest element to select.
 * @param left         lower bound index position  (inclusive)
 * @param right        upper bound index position  (inclusive)
 */
int selectKth (void **ar, int(*cmp)(const void *,const void *),
               int k, int left, int right) {
    do {
        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) {
            right = pivotIndex - 1;
        } else {
            /* otherwise k must decrease by the size being removed. */
            k -= (pivotIndex-left+1);
            left = pivotIndex + 1;
        }
    } while (1);
}