/** * @brief quicksort * @param first * @param last */ void quicksort(int first, int last){ int pivot,j,i; //qssteps++; if(first<last){ pivot=first; i=first; j=last; while(i<j){ struct nodelist_item **X1 = &nodeList[i]; struct nodelist_item **X2 = &nodeList[pivot]; while(( (*X1)->slot_gain >= (*X2)->slot_gain) && (i < last) ){ i++; X1 = &nodeList[i]; } X1 = &nodeList[j]; while( (*X1)->slot_gain < (*X2)->slot_gain ){ j--; X1 = &nodeList[j]; } if(i<j){ qsort_swap (i,j); } } //print_items(); qsort_swap (pivot,j); quicksort(first,j-1); quicksort(j+1,last); } }
static int qsort_partition(DArray* darray, int start, int end, compare cmp) { void* r = darray->contents[end]; int i = start - 1, j; for(j = start; j < end; j++) { if ( cmp(darray->contents[j],r) ) { i++; qsort_swap(&(darray->contents[i]), &(darray->contents[j])); } } qsort_swap(darray->contents[i+1], darray->contents[end]); return i+1; }
/* Main vertex Quicksort function. * A vertex p is below a vertex q if * py < qy or py == qy and px > qx * The vertices are sorted in order of * decreasing height. */ static void qsort_work(vertex_t** a, unsigned start, unsigned end) { unsigned pivot; unsigned i; vector_t pv; unsigned store; if (start >= end) return; else if (start == end - 1) { if (!vec_above(a[start]->vec, a[end]->vec)) qsort_swap(a, start, end); return; } // select pivot pivot = (start + end) / 2; pv = a[pivot]->vec; qsort_swap(a, pivot, end); store = start; for (i = start; i < end; ++i) { if (vec_above(a[i]->vec, pv)) { qsort_swap(a, i, store); store++; } } qsort_swap(a, store, end); if (start < store) qsort_work(a, start, store-1); if (store < end) qsort_work(a, store+1, end); }
STATIC void qsort_recur( char *left, char *right, int eltsize, int (*compfun)(char *, char *)) { char *i, *j; char *sameleft, *sameright; top: if (left + eltsize - 1 >= right) { return; } /* * partition element (reference for "same"ness */ sameleft = left + (((right - left) / eltsize) / 2) * eltsize; sameright = sameleft; i = left; j = right - eltsize; again: while (i < sameleft) { int comp; comp = (*compfun)(i, sameleft); if (comp == 0) { /* * Move to the "same" partition. */ /* * Shift the left part of the "same" partition to * the left, so that "same" elements stay in their * original order. */ sameleft -= eltsize; qsort_swap((int *) i, (int *) sameleft, eltsize); } else if (comp < 0) { /* * Stay in the "left" partition. */ i += eltsize; } else { /* * Should be moved to the "right" partition. * Wait until the next loop finds an appropriate * place to store this element. */ break; } } while (j > sameright) { int comp; comp = (*compfun)(sameright, j); if (comp == 0) { /* * Move to the right of the "same" partition. */ sameright += eltsize; qsort_swap((int *) sameright, (int *) j, eltsize); } else if (comp > 0) { /* * Move to the "left" partition. */ if (i == sameleft) { /* * Unfortunately, the "left" partition * has already been fully processed, so * we have to shift the "same" partition * to the right to free a "left" element. * This is done by moving the leftest same * to the right of the "same" partition. */ sameright += eltsize; qsort_rotate((int *) sameleft, (int*) sameright, (int *) j, eltsize); sameleft += eltsize; i = sameleft; } else { /* * Swap with the "left" partition element * waiting to be moved to the "right" * partition. */ qsort_swap((int *) i, (int *) j, eltsize); j -= eltsize; /* * Go back to the 1st loop. */ i += eltsize; goto again; } } else { /* * Stay in the "right" partition. */ j -= eltsize; } } if (i != sameleft) { /* * The second loop completed (the"right" partition is ok), * but we have to go back to the first loop, and deal with * the element waiting for a place in the "right" partition. * Let's shift the "same" zone to the left. */ sameleft -= eltsize; qsort_rotate((int *) sameright, (int *) sameleft, (int *) i, eltsize); sameright -= eltsize; j = sameright; /* * Go back to 1st loop. */ goto again; } /* * The partitions are correct now. Recur on the smallest side only. */ if (sameleft - left >= right - (sameright + eltsize)) { qsort_recur(sameright + eltsize, right, eltsize, compfun); /* * The "right" partition is now completely sorted. * The "same" partition is OK, so... * Ignore them, and start the loops again on the * "left" partition. */ right = sameleft; goto top; } else { qsort_recur(left, sameleft, eltsize, compfun); /* * The "left" partition is now completely sorted. * The "same" partition is OK, so ... * Ignore them, and start the loops again on the * "right" partition. */ left = sameright + eltsize; goto top; } }