int lomutoPartition(arrayT Array, counterT counter){ // ALGORITHM LomutoPartition(A[l..r]) //Partitions subarray by Lomuto’s algorithm using first element as pivot //Input: A subarray A[l..r] of array A[0..n − 1], defined by its left and right // indices l and r (l ≤ r) //Output: Partition of A[l..r] and the new position of the pivot if (Array->lIndex == Array->rIndex) return Array->lIndex; int p, s, i, median; median = medianOfThree(Array); swap(Array, median, Array->lIndex); p = Array->values[Array->lIndex]; s = Array->lIndex; for (i = Array->lIndex+1; i <= Array->rIndex; i++){ counter->lomuto->LoopCounts++; if (Array->values[i] < p){ s++; swap(Array, s, i); } } swap(Array, Array->lIndex, s); return s; }
/** * Find suitable pivotIndex to use for ar[left,right] with closed bound * on both sides. Goal is to consider groups of size b. In this code, b=3. * In the original BFPRT algorithm b=5. * * 1. Divide the elements into floor(n/b) groups of b elements and * find median value of each of these groups. Consider this set of * all medians to be the set M. * * 2. If |M| > b, then recursively apply until <=b groups are left * * 3. In the base case of the recursion, simply use INSERTION SORT to sort * remaining <=b median values and choose the median of this sorted set. */ static int medianOfMedians (void **ar, int(*cmp)(const void *,const void *), int left, int right, int gap) { int s, num; int span = 3*gap; /* less than group size? Insertion sort and return median. */ num = (right - left + 1) / span; if (num == 0) { _insertion (ar, cmp, left, right, gap); num = (right - left + 1)/gap; return left + gap*(num-1)/2; } /* set up all median values of groups of elements */ for (s = left; s+span < right; s += span) { medianOfThree(ar, s, gap, cmp); } /* Recursively apply to subarray [left, s-1] with increased gap * if more than 3 groupings remain. */ if (num < 3) { /* find median of this reduced set. BASE CASE */ _insertion (ar, cmp, left+span/2, right, span); return left + num*span/2; } else { return medianOfMedians (ar, cmp, left+span/2, s-1, span); } }
void QS::recSort(int left, int right) { if (left >= right) { return; } int pivot = medianOfThree(left, right); int center = partition(left, right, pivot); recSort(left, center - 1); recSort(center + 1, right); }
void QS::rec_sort(int left, int right){ //recursively sort the array //detect errors if((elements == NULL) || !(left < right) || (left < 0) || (left >= element_cnt) || (right >= element_cnt) || (right < 0)){ return; } if(left == right){ return; } int medIndex = medianOfThree(left, right); int pivotIndex = partition(left, right, medIndex); rec_sort(left, pivotIndex - 1); rec_sort(pivotIndex + 1, right); }
int hoarePartition(arrayT Array, counterT counter){ if (Array->lIndex == Array->rIndex) return Array->lIndex; int p, i, j; p = Array->values[medianOfThree(Array)]; i = Array->lIndex; j = Array->rIndex; while (i < j){ while (Array->values[i] < p){ i++; counter->hoare->LoopCounts++; } while (Array->values[j] > p){ j--; counter->hoare->LoopCounts++; } swap(Array, i, j); } swap(Array, i, j); return j; }
void quickSort(Iterator begin, Iterator end, Comparable cmp = Less<typename std::iterator_traits<Iterator>::value_type>()) { if(begin >= end) return; Iterator median = medianOfThree(begin, begin + (end-begin) / 2, end-1); typename std::iterator_traits<Iterator>::value_type pivotValue = *median; if(begin != median) *median = *begin; Iterator lo = begin, hi = end-1; while(lo < hi) { while( lo < hi && cmp(pivotValue, *hi) ) hi--; if(lo < hi) *(lo++) = *hi; while( lo < hi && cmp(*lo, pivotValue) ) lo++; if(lo < hi) *(hi--) = *lo; } *lo = pivotValue; quickSort(begin, lo, cmp); quickSort(lo+1, end, cmp); }
float selectPivot (float* arr, int size) { return medianOfThree (arr, 0, size/2, size-1); }