Rev 6391 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/** quick sort routine : sort a vector of floats, and carry along an int** x: vector to sort on* start: first element of x to sort* stop: last element of x to sort* cvec: a vector to carry along*/#include "rpart.h"#include "rpartproto.h"voidmysort(int start, int stop, double *x, int *cvec){int i, j, k;double temp, median;int tempd;while (start < stop) {/** first-- if the list is short, do an ordinary insertion sort*/if ((stop - start) < 11) {for (i = start + 1; i <= stop; i++) {temp = x[i];tempd = cvec[i];j = i - 1;while (j >= start && x[j] > temp) {x[j + 1] = x[j];cvec[j + 1] = cvec[j];j--;}x[j + 1] = temp;cvec[j + 1] = tempd;}return;}/** list is longer -- split it into two* I use the median of 3 values as the split point*/i = start;j = stop;k = (start + stop) / 2;median = x[k];if (x[i] >= x[k]) { /* one of j or k is smallest */if (x[j] > x[k]) { /* k is smallest */if (x[i] > x[j])median = x[j];elsemedian = x[i];}} else {if (x[j] < x[k]) {if (x[i] > x[j])median = x[i];elsemedian = x[j];}}/** Now actually do the partitioning* Because we must have at least one element >= median, "i"* will never run over the end of the array. Similar logic* applies to j.* A note on the use of "<" rather than "<=". If a list has lots* of identical elements, e.g. 80/100 are "3.5", then we will* often go to the swap step with x[i]=x[j]=median. But we will* get the pointers i and j to meet approximately in the middle of* the list, and that is THE important condition for speed in a* quicksort.**/while (i < j) {/** top pointer down till it points at something too large*/while (x[i] < median)i++;/** bottom pointer up until it points at something too small*/while (x[j] > median)j--;if (i < j) {if (x[i] > x[j]) { /* swap */temp = x[i];x[i] = x[j];x[j] = temp;tempd = cvec[i];cvec[i] = cvec[j];cvec[j] = tempd;}i++;j--;}}/** The while() step helps if there are lots of ties. It will break* the list into 3 parts: < median, ==median, >=median, of which only* the top and bottom ones need further attention.* The ">=" is needed because i may be == to j*/while (x[i] >= median && i > start)i--;while (x[j] <= median && j < stop)j++;/** list has been split, now do a recursive call* always recur on the shorter list, as this keeps the total* depth of nested calls to less than log_base2(n).*/if ((i - start) < (stop - j)) { /* top list is shorter */if ((i - start) > 0)mysort(start, i, x, cvec);start = j;} else { /* bottom list is shorter */if ((stop - j) > 0)mysort(j, stop, x, cvec);stop = i;}}}