/** * 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); } }
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); } }
/** * 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); } }
/** * 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); }