/** sorts array to make sum of weights lower than halfvar one side, returns edge between <halfvar and >halfvar parts of the set */ static hist_item *hist_item_sort_halfvar(hist_item *base, unsigned int len, double *const lowervar, const double halfvar) { do { const unsigned int l = qsort_partition(base, len), r = l+1; // check if sum of left side is smaller than half, // if it is, then it doesn't need to be sorted unsigned int t = 0; double tmpsum = *lowervar; while (t <= l && tmpsum < halfvar) tmpsum += base[t++].color_weight; if (tmpsum < halfvar) { *lowervar = tmpsum; } else { if (l > 0) { hist_item *res = hist_item_sort_halfvar(base, l, lowervar, halfvar); if (res) return res; } else { // End of left recursion. This will be executed in order from the first element. *lowervar += base[0].color_weight; if (*lowervar > halfvar) return &base[0]; } } if (len > r) { base += r; len -= r; // tail-recursive "call" } else { *lowervar += base[r].color_weight; return (*lowervar > halfvar) ? &base[r] : NULL; } } while(1); }
// quicksort void DArray_qsort_r(DArray* darray, int start, int end, compare cmp) { int pivot; if (start < end) { pivot = qsort_partition(darray, start, end, cmp); DArray_qsort_r(darray, start, pivot - 1, cmp); DArray_qsort_r(darray, pivot + 1, end, cmp); } }
static void quicksort(struct key_thing **x, unsigned int first, unsigned int last) { if (first < last) { unsigned int pivIndex = qsort_partition(x, first, last); if (pivIndex > 0) quicksort(x, first, pivIndex-1); quicksort(x, pivIndex+1, last); } }
void qsort_generic(void **arr, int len, cmp_fun cmp){ if(len < QSORT_MIN_LENGTH){ //putting a check for non-zero len here might speed things up insertion_sort_generic(arr, len, cmp); } else { int pivot_idx = qsort_partition(arr, 0, len-1, cmp); qsort_generic(arr, pivot_idx+1, cmp); qsort_generic(arr+(pivot_idx+1), len - (pivot_idx+1), cmp); } return; }
/** this is a simple qsort that completely sorts only elements between sort_start and +sort_len. Used to find median of the set. */ static void hist_item_sort_range(hist_item *base, unsigned int len, int sort_start, const int sort_len) { do { const unsigned int l = qsort_partition(base, len), r = l+1; if (sort_start+sort_len > 0 && (signed)l >= sort_start && l > 0) { hist_item_sort_range(base, l, sort_start, sort_len); } if (len > r && r < sort_start+sort_len && (signed)len > sort_start) { base += r; len -= r; sort_start -= r; // tail-recursive "call" } else return; } while(1); }
/** quick select algorithm */ static void hist_item_sort_range(hist_item *base, unsigned int len, unsigned int sort_start) { for(;;) { const unsigned int l = qsort_partition(base, len), r = l+1; if (l > 0 && sort_start < l) { len = l; } else if (r < len && sort_start > r) { base += r; len -= r; sort_start -= r; } else break; } }
int * quick_sort(int *list, int lower, int upper) { // Sorts a list of ints. int size = upper - lower + 1; int pivot_pos; if(list != NULL) { if(size > 1) { pivot_pos = qsort_partition(list, lower, upper); quick_sort(list, lower, pivot_pos - 1); quick_sort(list, pivot_pos + 1, upper); } } return list; }
void qsort_array(int low, int high) { if(low >= high) return; int q = qsort_partition(low, high); qsort_array(low, q-1); qsort_array(q+1, high); }