Exemple #1
0
void ssort2(char **a, int n, int depth,int* index)
{   int d, r, partval;
    int Diff=0;
    char **pa, **pb, **pc, **pd, **pl, **pm, **pn, *t;
    //~ if (n < 10) {
        //~ inssort(a, n, depth);
        //~ return;
    //~ }
    pl = a;
    pm = a + (n/2);
    pn = a + (n-1);
    if (n > 30) { // On big arrays, pseudomedian of 9
        d = (n/8);
        pl = med3(pl, pl+d, pl+2*d);
        pm = med3(pm-d, pm, pm+d);
        pn = med3(pn-2*d, pn-d, pn);
    }
    pm = med3(pl, pm, pn);
    Diff=pm-a;
    int *IndexA,*IndexB,*IndexC,*IndexD,*IndexN;
    swap2(a, pm);
    swap2Index(index,index+Diff);
    partval = ptr2char(a);
    pa = pb = a + 1;
    pc = pd = a + n-1;
    IndexA=IndexB=index+1;
    IndexC=IndexD=index+n-1;
    for (;;) {
        while (pb <= pc && (r = ptr2char(pb)-partval) <= 0) {
            if (r == 0) { swap2(pa, pb);swap2Index(IndexA, IndexB);pa++;IndexA++; }
            pb++;
            IndexB++;
        }
        while (pb <= pc && (r = ptr2char(pc)-partval) >= 0) {
            if (r == 0) { swap2(pc, pd); swap2Index(IndexC, IndexD);pd--;IndexD-- ;}
            pc--;
            IndexC--;
        }
        if (pb > pc) break;
        swap2(pb, pc);
        swap2Index(IndexB,IndexC);
        pb++;
        IndexB++;
        pc--;
        IndexC--;
    }
    pn = a + n;
    IndexN=index+n;
    r = min(pa-a, pb-pa);    vecswap2(a,  pb-r, r); vecswap2Index(index,IndexB-r,r);
    r = min(pd-pc, pn-pd-1); vecswap2(pb, pn-r, r); vecswap2Index(IndexB,IndexN-r,r);
    if ((r = pb-pa) > 1)
        ssort2(a, r, depth,index);
    if (ptr2char(a + r) != 0)
        ssort2(a + r, pa-a + pn-pd-1, depth+1,index+r);
    if ((r = pd-pc) > 1)
        ssort2(a + n-r, r, depth,index+n-r);
}
Exemple #2
0
	/* Subroutine for sort_split, algorithm by Bentley & McIlroy.*/
	int choose_pivot(const int_iter &p, int64_t n) {
	   int_iter pl, pm, pn;
	   int64_t s;
	   
	   pm=p+(n>>1);                 /* small arrays, middle element.*/
	   if (n>7) {
		  pl=p;
		  pn=p+n-1;
		  if (n>40) {               /* big arrays, pseudomedian of 9.*/
			 s=n>>3;
			 pl=med3(pl, pl+s, pl+s+s);
			 pm=med3(pm-s, pm, pm+s);
			 pn=med3(pn-s-s, pn-s, pn);
		  }
Exemple #3
0
void
rqsort(int *a, int n, double *x)
{
	int *pa, *pb, *pc, *pd, *pl, *pm, *pn;
	int  d, r;

	if (n < 7) { /* Insertion sort on small arrays */
		for (pm = a + 1; pm < a + n; pm++)
			for (pl = pm; pl > a && cmp(pl-1, pl, x) > 0; pl--)
				swap(pl, pl-1);
		return;
	}
	pm = a + (n/2);
	if (n > 7) {
		pl = a;
		pn = a + (n-1);
		if (n > 40) { /* On big arrays, pseudomedian of 9 */
			d = (n/8);
			pl = med3(pl, pl+d, pl+2*d, x);
			pm = med3(pm-d, pm, pm+d, x);
			pn = med3(pn-2*d, pn-d, pn, x);
		}
		pm = med3(pl, pm, pn, x); /* On mid arrays, med of 3 */
	}
	swap(a, pm); /* On tiny arrays, partition around middle */
	pa = pb = a + 1;
	pc = pd = a + (n-1);
	for (;;) {
		while (pb <= pc && (r = cmp(pb, a, x)) <= 0) {
			if (r == 0) { swap(pa, pb); pa++; }
			pb++;
		}
		while (pb <= pc && (r = cmp(pc, a, x)) >= 0) {
			if (r == 0) { swap(pc, pd); pd--; }
			pc--;
		}
		if (pb > pc) break;
		swap(pb, pc);
		pb++;
		pc--;
	}
	pn = a + n;
	r = minimum(pa-a,  pb-pa);   vecswap(a,  pb-r, r);
	r = minimum(pd-pc, pn-pd-1); vecswap(pb, pn-r, r);
	if ((r = pb-pa) > 1) rqsort(a, r, x);
	if ((r = pd-pc) > 1) rqsort(pn-r, r, x);
}
Exemple #4
0
int main() {
	float lux[SAMPLE_COUNT];
	float moisture[SAMPLE_COUNT];
	float lux_med;
	float moisture_med;
	int i;
	float median;

	// setup wiringpi spi
	wiringPiSPISetup(0, 1000000) ;

	// njl7502 (lux)
	for (i = SAMPLE_COUNT - 1; i >= 0; --i) {
		unsigned char data[] = {0b00000110, 0b00000000, 0b00000000};

		// send and receive data with spi
		wiringPiSPIDataRW (0, data, sizeof(data));
	
		// convert unit to lux
		lux[i] = (float)(((data[1] << 8) + data[2]) & 0x0FFF) * 1200.0f / 4096.0f;
	}

	// GROVE (moisture)
	for (i = SAMPLE_COUNT - 1; i >= 0; --i) {
		unsigned char data[] = {0b00000110, 0b01000000, 0b00000000};

		// send and receive data with spi
		wiringPiSPIDataRW (0, data, sizeof(data));
	
		// convert unit to lux
		moisture[i] = (float)(((data[1] << 8) + data[2]) & 0x0FFF) * 1930.0f / 4096.0f;
	}

#if SAMPLE_COUNT == 3
	lux_med = med3(lux);
	moisture_med = med3(moisture);
#else
# error "implement a function to find the median"
#endif	

	printf("illuminance: %.2f lux\n", lux_med);
	printf("moisture: %.2f %\n", moisture_med);
	
	return 0;
}
Exemple #5
0
void ssort2(unsigned char **a, int n, int depth)
{   int d, r, partval;
    unsigned char **pa, **pb, **pc, **pd, **pl, **pm, **pn, *t;
    if (n < 10) {
        inssort(a, n, depth);
        return;
    }
    pl = a;
    pm = a + (n/2);
    pn = a + (n-1);
    if (n > 30) { 
        d = (n/8);
        pl = med3(pl, pl+d, pl+2*d);
        pm = med3(pm-d, pm, pm+d);
        pn = med3(pn-2*d, pn-d, pn);
    }
    pm = med3(pl, pm, pn);
    swap2(a, pm);
    partval = ptr2char(a);
    pa = pb = a + 1;
    pc = pd = a + n-1;
    for (;;) {
        while (pb <= pc && (r = ptr2char(pb)-partval) <= 0) {
            if (r == 0) { swap2(pa, pb); pa++; }
            pb++;
        }
        while (pb <= pc && (r = ptr2char(pc)-partval) >= 0) {
            if (r == 0) { swap2(pc, pd); pd--; }
            pc--;
        }
        if (pb > pc) break;
        swap2(pb, pc);
        pb++;
        pc--;
    }
    pn = a + n;
    r = min(pa-a, pb-pa);    vecswap2(a,  pb-r, r);
    r = min(pd-pc, pn-pd-1); vecswap2(pb, pn-r, r);
    if ((r = pb-pa) > 1)
        ssort2(a, r, depth);
    if (ptr2char(a + r) != 0)
        ssort2(a + r, pa-a + pn-pd-1, depth+1);
    if ((r = pd-pc) > 1)
        ssort2(a + n-r, r, depth);
}
Exemple #6
0
static Rboolean sm_split3(double *x, double *y, int n, Rboolean do_ends)
{
    /* y[] := S(x[])  where S() = "sm_split3"  */
    int i, j;
    Rboolean chg = FALSE;

    for(i=0; i < n; i++)
	y[i] = x[i];

    /* Colin Goodall doesn't do splits near ends
       in spl() in Statlib's "smoother" code !! */
    if(do_ends && sptest(x, 1)) {
	chg = TRUE;
	y[1] = x[0];
	y[2] = med3(x[2], x[3], 3*x[3] - 2*x[4]);
    }

    for(i=2; i < n-3; i++)
	if(sptest(x, i)) { /* plateau at x[i] == x[i+1] */
	    /* at left : */
	    if(-1 < (j = imed3(x[i ], x[i-1], 3*x[i-1] - 2*x[i-2]))) {
		y[i]   = /* med3(.) = */ (j == 0)? x[i-1] : 3*x[i-1] - 2*x[i-2];
		chg = y[i] != x[i];
	    }
	    /* at right : */
	    if(-1 < (j = imed3(x[i+1], x[i+2], 3*x[i+2] - 2*x[i+3]))) {
		y[i+1] = /* med3(.) = */ (j == 0)? x[i+2] : 3*x[i+2] - 2*x[i+3];
		chg = y[i+1] != x[i+1];
	    }
	}
    if(do_ends && sptest(x, n-3)) {
	chg = TRUE;
	y[n-2] = x[n-1];
	y[n-3] = med3(x[n-3], x[n-4], 3*x[n-4] - 2*x[n-5]);
    }
    return(chg);
}
Exemple #7
0
void sort(Position *a, int left, int right){

	static int tmp[3];
	/* クイックソート(2次元座標)
	まずY座標を小さい順に上から並び替え、Y座標が同じ時はx座標が小さい方を上にする。

	* a.x     : ソートする配列(x)
	* a.y   : ソートする配列(y)
	* left  : ソートするデータの開始位置
	* right : ソートするデータの終了位置
	*/

	if (left < right) {

		int i = left, j = right;
		int pivot = med3((a + i)->s, ( a+  (i + (j - i) / 2)   )->s, (a + j)->s); /* (i+j)/2ではオーバーフローしてしまう */


		while (1) { /* (a+i)->s を pivot 以上と以下の集まりに分割する */

			while ((a+i)->s < pivot) { i++; } /* (a+i)->s[i] >= pivot となる位置を検索 */
			while (pivot < (a+j)->s) { j--; } /* (a+i)->s[j] <= pivot となる位置を検索 */
			
			if (i >= j)  { break; }
			
			hyouji(a, i, j);//表示関数
			tmp[0] = (a+i)->s; (a+i)->s = (a+j)->s; (a+j)->s = tmp[0]; /* (a+i)->s[i],(a+i)->s[j] を交換 */
			tmp[1] = (a+i)->y; (a+i)->y = (a+j)->y; (a+j)->y = tmp[1]; /* a[i],a[j] を交換 */
			tmp[2] = (a+i)->x; (a+i)->x = (a+j)->x; (a+j)->x = tmp[2]; /* a[i],a[j] を交換 */

			hyouji(a, i, j);//表示関数
			
			i++; j--;
		}
		sort(a, left, i - 1); /* 分割した左を再帰的にソート */
		sort(a, j + 1, right); /* 分割した右を再帰的にソート */
		
	}
	
}
Exemple #8
0
	void qsort (

/*  SYNOPSIS */
	void * a,
	size_t n,
	size_t es,
	int (* cmp)(const void *, const void *))

/*  FUNCTION
	Sort the array a. It contains n elements of the size es. Elements
	are compares using the function cmp().

    INPUTS
	a - The array to sort
	n - The number of elements in the array
	es - The size of a single element in the array
	cmp - The function which is called when two elements must be
		compared. The function gets the addresses of two elements
		of the array and must return 0 is both are equal, < 0 if
		the first element is less than the second and > 0 otherwise.

    RESULT
	None.

    NOTES

    EXAMPLE
	// Use this function to compare to stringpointers
	int cmp_strptr (const char ** sptr1, const char ** sptr2)
	{
	    return strcmp (*sptr1, *sptr2);
	}

	// Sort an array of strings
	char ** strings;

	// fill the array
	strings = malloc (sizeof (char *)*4);
	strings[0] = strdup ("h");
	strings[1] = strdup ("a");
	strings[2] = strdup ("f");
	strings[3] = strdup ("d");

	// Sort it
	qsort (strings, sizeof (char *), 4, (void *)cmp_strptr);

    BUGS

    SEE ALSO
	strcmp(), strncmp(), memcmp(), strcasecmp(), strncasecmp()

    INTERNALS

******************************************************************************/
{
	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
	int d, r, swaptype, swap_cnt;

	
loop:	SWAPINIT(a, es);
	swap_cnt = 0;
	if (n < 7) {
		for (pm = a + es; pm < (char *) a + n * es; pm += es)
			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
			     pl -= es)
				swap(pl, pl - es);
		return;
	}
	pm = a + (n / 2) * es;
	if (n > 7) {
		pl = a;
		pn = a + (n - 1) * es;
		if (n > 40) {
			d = (n / 8) * es;
			pl = (char *)med3(pl, pl + d, pl + 2 * d, cmp);
			pm = (char *)med3(pm - d, pm, pm + d, cmp);
			pn = (char *)med3(pn - 2 * d, pn - d, pn, cmp);
		}
		pm = (char *)med3(pl, pm, pn, cmp);
	}
	swap(a, pm);
	pa = pb = a + es;

	pc = pd = a + (n - 1) * es;
	for (;;) {
		while (pb <= pc && (r = cmp(pb, a)) <= 0) {
			if (r == 0) {
				swap_cnt = 1;
				swap(pa, pb);
				pa += es;
			}
			pb += es;
		}
		while (pb <= pc && (r = cmp(pc, a)) >= 0) {
			if (r == 0) {
				swap_cnt = 1;
				swap(pc, pd);
				pd -= es;
			}
			pc -= es;
		}
		if (pb > pc)
			break;
		swap(pb, pc);
		swap_cnt = 1;
		pb += es;
		pc -= es;
	}
	if (swap_cnt == 0) {  /* Switch to insertion sort */
		for (pm = a + es; pm < (char *) a + n * es; pm += es)
			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
			     pl -= es)
				swap(pl, pl - es);
		return;
	}

	pn = a + n * es;
	r = min(pa - (char *)a, pb - pa);
	vecswap(a, pb - r, r);
	r = min(pd - pc, pn - pd - es);
	vecswap(pb, pn - r, r);
	if ((r = pb - pa) > es)
		qsort(a, r / es, es, cmp);
	if ((r = pd - pc) > es) {
		/* Iterate rather than recurse to save stack space */
		a = pn - r;
		n = r / es;
		goto loop;
	}
/*		qsort(pn - r, r / es, es, cmp);*/
}
void
qsort_arg(void *a, size_t n, size_t es, qsort_arg_comparator cmp, void *arg)
{
	char	   *pa,
			   *pb,
			   *pc,
			   *pd,
			   *pl,
			   *pm,
			   *pn;
	int			d,
				r,
				swaptype,
				presorted;

loop:SWAPINIT(a, es);
	if (n < 7)
	{
		for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
			for (pl = pm; pl > (char *) a && cmp(pl - es, pl, arg) > 0;
				 pl -= es)
				swap(pl, pl - es);
		return;
	}
	presorted = 1;
	for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
	{
		if (cmp(pm - es, pm, arg) > 0)
		{
			presorted = 0;
			break;
		}
	}
	if (presorted)
		return;
	pm = (char *) a + (n / 2) * es;
	if (n > 7)
	{
		pl = (char *) a;
		pn = (char *) a + (n - 1) * es;
		if (n > 40)
		{
			d = (n / 8) * es;
			pl = med3(pl, pl + d, pl + 2 * d, cmp, arg);
			pm = med3(pm - d, pm, pm + d, cmp, arg);
			pn = med3(pn - 2 * d, pn - d, pn, cmp, arg);
		}
		pm = med3(pl, pm, pn, cmp, arg);
	}
	swap(static_cast<char *>(a), pm);
	pa = pb = (char *) a + es;
	pc = pd = (char *) a + (n - 1) * es;
	for (;;)
	{
		while (pb <= pc && (r = cmp(pb, a, arg)) <= 0)
		{
			if (r == 0)
			{
				swap(pa, pb);
				pa += es;
			}
			pb += es;
		}
		while (pb <= pc && (r = cmp(pc, a, arg)) >= 0)
		{
			if (r == 0)
			{
				swap(pc, pd);
				pd -= es;
			}
			pc -= es;
		}
		if (pb > pc)
			break;
		swap(pb, pc);
		pb += es;
		pc -= es;
	}
	pn = (char *) a + n * es;
	r = Min(pa - (char *) a, pb - pa);
	vecswap(static_cast<char *>(a), pb - r, r);
	r = Min(pd - pc, pn - pd - es);
	vecswap(pb, pn - r, r);
	if ((r = pb - pa) > es)
		qsort_arg(a, r / es, es, cmp, arg);
	if ((r = pd - pc) > es)
	{
		/* Iterate rather than recurse to save stack space */
		a = pn - r;
		n = r / es;
		goto loop;
	}
/*		qsort_arg(pn - r, r / es, es, cmp, arg);*/
}
Exemple #10
0
void
qsort(void *a, size_t n, size_t es, cmp_t *cmp)
#endif
{
    char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
    size_t d, r;
    int cmp_result;
    int swaptype, swap_cnt;

loop:   SWAPINIT(a, es);
    swap_cnt = 0;
    if (n < 7) {
        for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
            for (pl = pm;
                 pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
                 pl -= es)
                swap(pl, pl - es);
        return;
    }
    pm = (char *)a + (n / 2) * es;
    if (n > 7) {
        pl = (char *)a;
        pn = (char *)a + (n - 1) * es;
        if (n > 40) {
            d = (n / 8) * es;
            pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
            pm = med3(pm - d, pm, pm + d, cmp, thunk);
            pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
        }
        pm = med3(pl, pm, pn, cmp, thunk);
    }
    swap(a, pm);
    pa = pb = (char *)a + es;

    pc = pd = (char *)a + (n - 1) * es;
    for (;;) {
        while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) {
            if (cmp_result == 0) {
                swap_cnt = 1;
                swap(pa, pb);
                pa += es;
            }
            pb += es;
        }
        while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) {
            if (cmp_result == 0) {
                swap_cnt = 1;
                swap(pc, pd);
                pd -= es;
            }
            pc -= es;
        }
        if (pb > pc)
            break;
        swap(pb, pc);
        swap_cnt = 1;
        pb += es;
        pc -= es;
    }
    if (swap_cnt == 0) {  /* Switch to insertion sort */
        for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
            for (pl = pm;
                 pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
                 pl -= es)
                swap(pl, pl - es);
        return;
    }

    pn = (char *)a + n * es;
    r = min(pa - (char *)a, pb - pa);
    vecswap((char*)a, (char *)(pb - r), r);
    // !!! Ren/C: pn - pd - es => (long)(pn - pd - ps) for -Wsign-compare
    r = min(pd - pc, (long)(pn - pd - es));
    vecswap(pb, pn - r, r);
    if ((r = pb - pa) > es)
#ifdef I_AM_QSORT_R
        qsort_r(a, r / es, es, thunk, cmp);
#else
        qsort(a, r / es, es, cmp);
#endif
    if ((r = pd - pc) > es) {
        /* Iterate rather than recurse to save stack space */
        a = pn - r;
        n = r / es;
        goto loop;
    }
/*      qsort(pn - r, r / es, es, cmp);*/
}
Exemple #11
0
void NS_QuickSort (
	void *a,
	unsigned int n,
    unsigned int es,
	cmp_t *cmp,
	void *data
    )
{
	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
	int d, r, swaptype;

loop:	SWAPINIT(a, es);
	/* Use insertion sort when input is small */
	if (n < 7) {
		for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
			for (pl = pm; pl > (char *)a && cmp(pl - es, pl, data) > 0;
			     pl -= es)
				swap(pl, pl - es);
		return;
	}
	/* Choose pivot */
	pm = (char *)a + (n / 2) * es;
	if (n > 7) {
		pl = (char *)a;
		pn = (char *)a + (n - 1) * es;
		if (n > 40) {
			d = (n / 8) * es;
			pl = med3(pl, pl + d, pl + 2 * d, cmp, data);
			pm = med3(pm - d, pm, pm + d, cmp, data);
			pn = med3(pn - 2 * d, pn - d, pn, cmp, data);
		}
		pm = med3(pl, pm, pn, cmp, data);
	}
	swap(a, pm);
	pa = pb = (char *)a + es;

	pc = pd = (char *)a + (n - 1) * es;
	/* loop invariants:
	 * [a, pa) = pivot
	 * [pa, pb) < pivot
	 * [pb, pc + es) unprocessed
	 * [pc + es, pd + es) > pivot
	 * [pd + es, pn) = pivot
	 */
	for (;;) {
		while (pb <= pc && (r = cmp(pb, a, data)) <= 0) {
			if (r == 0) {
				swap(pa, pb);
				pa += es;
			}
			pb += es;
		}
		while (pb <= pc && (r = cmp(pc, a, data)) >= 0) {
			if (r == 0) {
				swap(pc, pd);
				pd -= es;
			}
			pc -= es;
		}
		if (pb > pc)
			break;
		swap(pb, pc);
		pb += es;
		pc -= es;
	}
	/* Move pivot values */
	pn = (char *)a + n * es;
	r = XPCOM_MIN(pa - (char *)a, pb - pa);
	vecswap(a, pb - r, r);
	r = XPCOM_MIN<size_t>(pd - pc, pn - pd - es);
	vecswap(pb, pn - r, r);
	/* Recursively process partitioned items */
	if ((r = pb - pa) > (int)es)
        NS_QuickSort(a, r / es, es, cmp, data);
	if ((r = pd - pc) > (int)es) {
		/* Iterate rather than recurse to save stack space */
		a = pn - r;
		n = r / es;
		goto loop;
	}
/*		NS_QuickSort(pn - r, r / es, es, cmp, data);*/
}
Exemple #12
0
/*--------------------------------------------------------------------------*/
void sciqsort(char *a, char *tab, int flag, int n, int es, int es1, int (*cmp)(), int (*swapcode)(), int (*lswapcodeind)())
{
    char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
    char *taba, *tabb, *tabc, *tabd, *tabl, *tabm, *tabn;
    int d, dind, r, r1,  swap_cnt;

loop:
    swap_cnt = 0;
    if (n < 7)   /* Insertion sort on smallest arrays */
    {
        for (pm = a + es, tabm = tab + es1 ; pm < (char *) a + n * es; pm += es, tabm += es1 )
        {
            for (pl = pm, tabl = tabm ; pl > (char *) a && cmp(pl - es, pl, tabl - es1, tabl, flag) > 0;  pl -= es, tabl -= es1)
            {
                swapind(tabl, tabl - es1);
                swap(pl, pl - es);
            }
        }

        return;
    }

    /*Determine the pivot */
    pm = a + (n / 2) * es;/* Small arrays, middle element */
    tabm = tab + (n / 2) * es1 ;

    pn = a + (n - 1) * es;
    tabn = tab + (n - 1) * es1;

    if (n > 7)
    {
        pl = a;
        tabl = tab;
        if (n > 40)  /* Big arrays, pseudomedian of 9 */
        {
            dind = (n / 8) * es1;
            d =   (n / 8) * es;
            med3(pl, tabl, pl, pl + d, pl + 2 * d, tabl, tabl + dind, tabl + 2 * dind, cmp);
            med3(pm, tabm, pm - d, pm, pm + d, tabm - dind, tabm, tabm + dind, cmp);
            med3(pn, tabn, pn - 2 * d, pn - d, pn, tabn - 2 * dind, tabn - dind, tabn, cmp);
        }
        med3(pm, tabm, pl, pm, pn, tabl, tabm, tabn, cmp);
    }

    /* Put it at the first position */
    /* Partionning */
    if (cmp(pn, a, tabn, tab, flag))
    {
        swapind(tab, tabn);
        swap(a, pn);
    }

    /* pointers on data array */
    pa = pb = a + es;/* pa and pb start from the beginning of the array */
    pc = pd = a + (n - 1) * es;/* pc and pd start from the end of the array */

    /* similar pointers for index array */
    taba = tabb = tab + es1;
    tabc = tabd = tab + (n - 1) * es1;

    /* here we have
    |a  |pa                            | pc|
    |a  |pb                            | pd|
    |*a |                ?             | ? |
    */
    for (;;)
    {
        /* increase the pointer pb while it points on values lesser  than the pivot (pointer a) */
        while (pb <= pc && (r = cmp(pb, a, tabb, tab, flag)) <= 0)
        {
            if (r == 0)  /*The pivot and  value pointed to by pb are equal */
            {
                /* store the equal value at the location pa and increase pa */
                swap_cnt = 1;
                swapind(taba, tabb);
                taba += es1;
                swap(pa, pb);
                pa += es;
            }
            pb += es;/* next number */
            tabb += es1;
        }

        /* here pb points on a value greater than the pivot */
        /* decrease the pointer pc while it points on a value greater than the pivot (pointer a) */
        while (pb <= pc && (r = cmp(pc, a, tabc, tab, flag)) >= 0)
        {
            if (r == 0)  /*The pivot and  value pointed to by pc are equal */
            {
                /* store the equal value at the location pd and decrease pd */
                swap_cnt = 1;
                swapind(tabc, tabd);
                tabd -= es1;
                swap(pc, pd);
                pd -= es;
            }
            pc -= es;
            tabc -= es1;
        }
        /* here pc points on a value lesser than the pivot */
        if (pb > pc)
        {
            /* here we have
            |a      |pa      |pc|pb     pd|      $|
            |   =*a |    <*a |       >*a  | =*a  $|
            */
            /* partition is done */
            break;
        }
        /*here
        pc  points on a value lesser than the pivot
        and
        pb points on a value greater than the pivot
        swap the values
        */
        swapind(tabb, tabc);
        tabb += es1;
        tabc -= es1;
        swap(pb, pc);
        swap_cnt = 1;
        /* increase pb and decrease pc */
        pb += es;
        pc -= es;
        /* here we have
        |a      |pa      |pb       pc|       pd|      $|
        |   =*a |    <*a |     ?     |    >*a  | =*a  $|
        */
    }

    if (swap_cnt == 0)    /* Switch to insertion sort */
    {
        for (pm = a + es, tabm = tab + es1 ; pm < (char *) a + n * es; pm += es, tabm += es1)
        {
            for (pl = pm, tabl = tabm ; pl > (char *) a && cmp(pl - es, pl, tabl - es1, tabl, flag) > 0;  pl -= es, tabl -= es1)
            {
                swapind(tabl, tabl - es1);
                swap(pl, pl - es);
            }
        }
        return;
    }
    /* put the equal values in the middle */
    pn = a + n * es;
    r = (int)Min(pa - (char *)a, pb - pa);
    vecswap(a, pb - r, r);

    tabn = tab + n * es1 ;
    r1 = (int)Min(taba - (char *) tab, tabb - taba);
    vecswapind(tab, tabb - r1, r1);

    r = (int)Min(pd - pc, pn - pd - es);
    vecswap(pb, pn - r, r);

    r1 = (int)Min(tabd - tabc, tabn - tabd - es1 );
    vecswapind(tabb, tabn - r1, r1);

    if ((r = (int)(pb - pa)) > es )
        /* recall  sciqsort for the lower part */
    {
        sciqsort(a, tab, flag, r / es, es, es1, cmp, swapcode, lswapcodeind);
    }
    if ((r = (int)(pd - pc)) > es)
    {
        /* Iterate rather than recurse to save stack space */
        a = pn - r;
        tab = tabn - (tabd - tabc);
        n = r / es;
        goto loop;
    }
}
Exemple #13
0
void
qsort(
	void		*basep,
	size_t		nrec,
	size_t		rsiz,
	int		(*cmp)(const void *, const void *))
{
	size_t		i;		/* temporary variable */

	/* variables used by swap */
	void		(*swapf)(char *, char *, size_t);
	size_t		loops;

	/* variables used by sort */
	stk_t		stack[8 * sizeof (nrec) + 1];
	stk_t		*sp;
	char		*b_lim;		/* bottom limit */
	char		*b_dup;		/* bottom duplicate */
	char		*b_par;		/* bottom partition */
	char		*t_lim;		/* top limit */
	char		*t_dup;		/* top duplicate */
	char		*t_par;		/* top partition */
	char		*m1, *m2, *m3;	/* median pointers */
	uintptr_t	d_bytelength;	/* byte length of duplicate records */
	int		b_nrec;
	int		t_nrec;
	int		cv;		/* results of compare (bottom / top) */

	/*
	 * choose a swap function based on alignment and size
	 *
	 * The qsort function sorts an array of fixed length records.
	 * We have very limited knowledge about the data record itself.
	 * It may be that the data record is in the array we are sorting
	 * or it may be that the array contains pointers or indexes to
	 * the actual data record and all that we are sorting is the indexes.
	 *
	 * The following decision will choose an optimal swap function
	 * based on the size and alignment of the data records
	 *   swapp64	will swap 64 bit pointers
	 *   swapp32	will swap 32 bit pointers
	 *   swapi	will swap an array of 32 bit integers
	 *   swapb	will swap an array of 8 bit characters
	 *
	 * swapi and swapb will also require the variable loops to be set
	 * to control the length of the array being swapped
	 */
	if ((((uintptr_t)basep & (sizeof (uint64_t) - 1)) == 0) &&
	    (rsiz == sizeof (uint64_t))) {
		loops = 1;
		swapf = (void (*)(char *, char *, size_t))swapp64;
	} else if ((((uintptr_t)basep & (sizeof (uint32_t) - 1)) == 0) &&
	    (rsiz == sizeof (uint32_t))) {
		loops = 1;
		swapf = (void (*)(char *, char *, size_t))swapp32;
	} else if ((((uintptr_t)basep & (sizeof (uint32_t) - 1)) == 0) &&
	    ((rsiz & (sizeof (uint32_t) - 1)) == 0)) {
		loops = rsiz / sizeof (int);
		swapf = (void (*)(char *, char *, size_t))swapi;
	} else {
		loops = rsiz;
		swapf = swapb;
	}

	/*
	 * qsort is a partitioning sort
	 *
	 * the stack is the bookkeeping mechanism to keep track of all
	 * the partitions.
	 *
	 * each sort pass takes one partition and sorts it into two partitions.
	 * at the top of the loop we simply take the partition on the top
	 * of the stack and sort it. See the comments at the bottom
	 * of the loop regarding which partitions to add in what order.
	 *
	 * initially put the whole partition on the stack
	 */
	sp = stack;
	sp->b_lim = (char *)basep;
	sp->nrec = nrec;
	sp++;
	while (sp > stack) {
		sp--;
		b_lim = sp->b_lim;
		nrec = sp->nrec;

		/*
		 * a linear insertion sort i faster than a qsort for
		 * very small number of records (THRESH_L)
		 *
		 * if number records < threshold use linear insertion sort
		 *
		 * this also handles the special case where the partition
		 * 0 or 1 records length.
		 */
		if (nrec < THRESH_L) {
			/*
			 * Linear insertion sort
			 */
			t_par = b_lim;
			for (i = 1; i < nrec; i++) {
				t_par += rsiz;
				b_par = t_par;
				while (b_par > b_lim) {
					b_par -= rsiz;
					if ((*cmp)(b_par, b_par + rsiz) <= 0) {
						break;
					}
					(*swapf)(b_par, b_par + rsiz, loops);
				}
			}

			/*
			 * a linear insertion sort will put all records
			 * in their final position and will not create
			 * subpartitions.
			 *
			 * therefore when the insertion sort is complete
			 * just go to the top of the loop and get the
			 * next partition to sort.
			 */
			continue;
		}

		/* quicksort */

		/*
		 * choose a pivot record
		 *
		 * Ideally the pivot record will divide the partition
		 * into two equal parts. however we have to balance the
		 * work involved in selecting the pivot record with the
		 * expected benefit.
		 *
		 * The choice of pivot record depends on the number of
		 * records in the partition
		 *
		 * for small partitions (nrec < THRESH_M3)
		 *   we just select the record in the middle of the partition
		 *
		 * if (nrec >= THRESH_M3 && nrec < THRESH_M9)
		 *   we select three values and choose the median of 3
		 *
		 * if (nrec >= THRESH_M9)
		 *   then we use an approximate median of 9
		 *   9 records are selected and grouped in 3 groups of 3
		 *   the median of each of these 3 groups is fed into another
		 *   median of 3 decision.
		 *
		 * Each median of 3 decision is 2 or 3 compares,
		 * so median of 9 costs between 8 and 12 compares.
		 *
		 * i is byte distance between two consecutive samples
		 * m2 will point to the pivot record
		 */
		if (nrec < THRESH_M3) {
			m2 = b_lim + (nrec / 2) * rsiz;
		} else if (nrec < THRESH_M9) {
			/* use median of 3 */
			i = ((nrec - 1) / 2) * rsiz;
			m2 = med3(b_lim, b_lim + i, b_lim + 2 * i);
		} else {
			/* approx median of 9 */
			i = ((nrec - 1) / 8) * rsiz;
			m1 = med3(b_lim, b_lim +  i, b_lim + 2 * i);
			m2 = med3(b_lim + 3 * i, b_lim + 4 * i, b_lim + 5 * i);
			m3 = med3(b_lim + 6 * i, b_lim + 7 * i, b_lim + 8 * i);
			m2 = med3(m1, m2, m3);
		}

		/*
		 * quick sort partitioning
		 *
		 * The partition limits are defined by bottom and top pointers
		 * b_lim and t_lim.
		 *
		 * qsort uses a fairly standard method of moving the
		 * partitioning pointers, b_par and t_par, to the middle of
		 * the partition and exchanging records that are in the
		 * wrong part of the partition.
		 *
		 * Two enhancements have been made to the basic algorithm.
		 * One for handling duplicate records and one to minimize
		 * the number of swaps.
		 *
		 * Two duplicate records pointers are (b_dup and t_dup) are
		 * initially set to b_lim and t_lim.  Each time a record
		 * whose sort key value is equal to the pivot record is found
		 * it will be swapped with the record pointed to by
		 * b_dup or t_dup and the duplicate pointer will be
		 * incremented toward the center.
		 * When partitioning is complete, all the duplicate records
		 * will have been collected at the upper and lower limits of
		 * the partition and can easily be moved adjacent to the
		 * pivot record.
		 *
		 * The second optimization is to minimize the number of swaps.
		 * The pointer m2 points to the pivot record.
		 * During partitioning, if m2 is ever equal to the partitioning
		 * pointers, b_par or t_par, then b_par or t_par just moves
		 * onto the next record without doing a compare.
		 * If as a result of duplicate record detection,
		 * b_dup or t_dup is ever equal to m2,
		 * then m2 is changed to point to the duplicate record and
		 * b_dup or t_dup is incremented with out swapping records.
		 *
		 * When partitioning is done, we may not have the same pivot
		 * record that we started with, but we will have one with
		 * an equal sort key.
		 */
		b_dup = b_par		= b_lim;
		t_dup = t_par = t_lim	= b_lim + rsiz * (nrec - 1);
		for (;;) {

			/* move bottom pointer up */
			for (; b_par <= t_par; b_par += rsiz) {
				if (b_par == m2) {
					continue;
				}
				cv = cmp(b_par, m2);
				if (cv > 0) {
					break;
				}
				if (cv == 0) {
					if (b_dup == m2) {
						m2 = b_par;
					} else if (b_dup != b_par) {
						(*swapf)(b_dup, b_par, loops);
					}
					b_dup += rsiz;
				}
			}

			/* move top pointer down */
			for (; b_par < t_par; t_par -= rsiz) {
				if (t_par == m2) {
					continue;
				}
				cv = cmp(t_par, m2);
				if (cv < 0) {
					break;
				}
				if (cv == 0) {
					if (t_dup == m2) {
						m2 = t_par;
					} else if (t_dup != t_par) {
						(*swapf)(t_dup, t_par, loops);
					}
					t_dup -= rsiz;
				}
			}

			/* break if we are done partitioning */
			if (b_par >= t_par) {
				break;
			}

			/* exchange records at upper and lower break points */
			(*swapf)(b_par, t_par, loops);
			b_par += rsiz;
			t_par -= rsiz;
		}

		/*
		 * partitioning is now complete
		 *
		 * there are two termination conditions from the partitioning
		 * loop above.  Either b_par or t_par have crossed or
		 * they are equal.
		 *
		 * we need to swap the pivot record to its final position
		 * m2 could be in either the upper or lower partitions
		 * or it could already be in its final position
		 */
		/*
		 * R[b_par] > R[m2]
		 * R[t_par] < R[m2]
		 */
		if (t_par < b_par) {
			if (m2 < t_par) {
				(*swapf)(m2, t_par, loops);
				m2 = b_par = t_par;
			} else if (m2 > b_par) {
				(*swapf)(m2, b_par, loops);
				m2 = t_par = b_par;
			} else {
				b_par = t_par = m2;
			}
		} else {
			if (m2 < t_par) {
				t_par = b_par = t_par - rsiz;
			}
			if (m2 != b_par) {
				(*swapf)(m2, b_par, loops);
			}
			m2 = t_par;
		}

		/*
		 * move bottom duplicates next to pivot
		 * optimized to eliminate overlap
		 */
		d_bytelength = b_dup - b_lim;
		if (b_par - b_dup < d_bytelength) {
			b_dup = b_lim + (b_par - b_dup);
		}
		while (b_dup > b_lim) {
			b_dup -= rsiz;
			b_par -= rsiz;
			(*swapf)(b_dup, b_par, loops);
		}
		b_par = m2 - d_bytelength;

		/*
		 * move top duplicates next to pivot
		 */
		d_bytelength = t_lim - t_dup;
		if (t_dup - t_par < d_bytelength) {
			t_dup = t_lim - (t_dup - t_par);
		}
		while (t_dup < t_lim) {
			t_dup += rsiz;
			t_par += rsiz;
			(*swapf)(t_dup, t_par, loops);
		}
		t_par = m2 + d_bytelength;

		/*
		 * when a qsort pass completes there are three partitions
		 * 1) the lower contains all records less than pivot
		 * 2) the upper contains all records greater than pivot
		 * 3) the pivot partition contains all record equal to pivot
		 *
		 * all records in the pivot partition are in their final
		 * position and do not need to be accounted for by the stack
		 *
		 * when adding partitions to the stack
		 * it is important to add the largest partition first
		 * to prevent stack overflow.
		 *
		 * calculate number of unsorted records in top and bottom
		 * push resulting partitions on stack
		 */
		b_nrec = (b_par - b_lim) / rsiz;
		t_nrec = (t_lim - t_par) / rsiz;
		if (b_nrec < t_nrec) {
			sp->b_lim = t_par + rsiz;
			sp->nrec = t_nrec;
			sp++;
			sp->b_lim = b_lim;
			sp->nrec = b_nrec;
			sp++;
		} else {
			sp->b_lim = b_lim;
			sp->nrec = b_nrec;
			sp++;
			sp->b_lim = t_par + rsiz;
			sp->nrec = t_nrec;
			sp++;
		}
	}
}
void
base_quicksort7(unsigned int a[], int N)
{
    int l, r;
    int i;
    int m;
    int il, ir; /* names follow pl, pm, and pn from bently/mcilroy. used ir instead of in */

    stackinit(N);

    describe_predictor(&global_predictor[0], "i");
    describe_predictor(&global_predictor[1], "j");
    describe_predictor(&global_predictor[2], "partition end");
    describe_predictor(&global_predictor[3], "insertion");
    describe_predictor(&global_predictor[4], "median");
    /*	describe_predictor(&global_predictor[4], "median of 7 ab"); */
    describe_predictor(&global_predictor[5], "median of 7 bc");
    describe_predictor(&global_predictor[6], "median of 7 ac");
    describe_predictor(&global_predictor[7], "median of 7 cb");
    describe_predictor(&global_predictor[8], "median of 7 ca");
    describe_predictor(&global_predictor[9], "median of 7 ab2");
    describe_predictor(&global_predictor[10], "median of 7 bc2");
    describe_predictor(&global_predictor[11], "median of 7 ac2");
    describe_predictor(&global_predictor[12], "median of 7 cb2");
    describe_predictor(&global_predictor[13], "median of 7 ca2");
    describe_predictor(&global_predictor[14], "median of 3 cmp1");
    describe_predictor(&global_predictor[15], "median of 3 cmp2");
    describe_predictor(&global_predictor[16], "median of 3 cmp3");


    r = N-1;
    l = 0;

    while(1)
    {
        int n = r - l;
        int n6 = n/6;
        int n3 = n/3;
        if (r - l <= THRESHHOLD)
        {
            if (stackempty())
                break;

            l = pop();
            r = pop();
            continue;
        }

        /* pseudo - Median of 7 partitioning*/
        m = (l+r)/2;
        if (n > 40)
        {

            il = med3(a, l, l + n6, l + n3);

            /* the 2 is for seperate branch predictors, as it's inlined */
            ir = med3_2(a, r - n3, r - n6, r);

            exch(a[l], a[il]);
            exch(a[r], a[ir]);
            exch(a[m], a[r-1]);
        }


        pred_compexch(a[l], a[r-1], 14);
        pred_compexch(a[l], a[r], 15);
        pred_compexch(a[r-1], a[r], 16);

        i = partition(a,l+1,r-1);

        /* here is the bug */
        /* then key is being copied more times than necessary. the reason for this is that it is not being removed when it is taken as the key */
        /* instead, it is being put in place more than once */
        /* example: i == 1, j == 10; key = a[1]; key < pivot, so key is swapped with a[2], the key is now in a[1] and a[2]. uh oh  */
        if (i-l > r-i)
        {
            push(i-1,l);
            l = i+1;
        }
        else
        {
            push(r,i+1);
            r = i-1;
        }
    }

    stackclear();
    /* the +1 isnt immediately obvious. its because THRESHHOLD is the difference between l and r up above */
    if (2*THRESHHOLD > N) insertion_sentinel(a,N);
    else insertion_sentinel(a,2*THRESHHOLD);

    insertion(a, N);

    /* add the predictors up */
    add_predictor(&global_predictor[4], &global_predictor[5]);
    add_predictor(&global_predictor[4], &global_predictor[6]);
    add_predictor(&global_predictor[4], &global_predictor[7]);
    add_predictor(&global_predictor[4], &global_predictor[8]);
    add_predictor(&global_predictor[4], &global_predictor[9]);
    add_predictor(&global_predictor[4], &global_predictor[10]);
    add_predictor(&global_predictor[4], &global_predictor[11]);
    add_predictor(&global_predictor[4], &global_predictor[12]);
    add_predictor(&global_predictor[4], &global_predictor[13]);
    add_predictor(&global_predictor[4], &global_predictor[14]);
    add_predictor(&global_predictor[4], &global_predictor[15]);
    add_predictor(&global_predictor[4], &global_predictor[16]);
    init_predictor(&global_predictor[5]);
    init_predictor(&global_predictor[6]);
    init_predictor(&global_predictor[7]);
    init_predictor(&global_predictor[8]);
    init_predictor(&global_predictor[9]);
    init_predictor(&global_predictor[10]);
    init_predictor(&global_predictor[11]);
    init_predictor(&global_predictor[12]);
    init_predictor(&global_predictor[13]);
    init_predictor(&global_predictor[14]);
    init_predictor(&global_predictor[15]);
    init_predictor(&global_predictor[16]);
}
Exemple #15
0
//Stable sort of sequences
void SArrayIndex::sort(quint32* x, int off, int len) {
    // Insertion sort on smallest arrays
    if (len < 7) {
        for (int i=off; i<len+off; i++){
            for (int j=i; j > off && compare(x[j-1],x[j])>0; j--) {
                qSwap(x[j], x[j-1]);
            }
        }
        return;
    }

    // Choose a partition element, v
    quint32 m = off + len / 2;       // Small arrays, middle element
    if (len > 7) {
        quint32 l = off;
        quint32 n = off + len - 1;
        if (len > 40) {        // Big arrays, pseudo median of 9
            quint32 s = len / 8;
            l = med3(x, l,     l+s, l+2*s);
            m = med3(x, m-s,   m,   m+s);
            n = med3(x, n-2*s, n-s, n);
        }
        m = med3(x, l, m, n); // Mid-size, med of 3
    }
    quint32 v = x[m];

    // Establish Invariant: v* (<v)* (>v)* v*
    int a = off, b = off, c = off + len - 1, d = c;
    while(true) {
        int cr;
        while (b <= c && (cr = compare(v, x[b])) >= 0) {
            if (cr == 0) {
                qSwap(x[a],x[b]);
                a++;
            }
            b++;
        }
        while (c >= b && (cr = compare(x[c], v)) >=0 ) {
            if (cr == 0) {
                qSwap(x[c],x[d]);
                d--;
            }
            c--;
        }
        if (b > c) {
            break;
        }
        qSwap(x[b], x[c]);
        b++; c--;
    }

    // Swap partition elements back to middle
    int s, n = off + len;
    s = qMin(a-off, b-a  );  vecswap(x, off, b-s, s);
    s = qMin(d-c,   n-d-1);  vecswap(x, b,   n-s, s);

    // Recursively sort non-partition-elements
    if ((s = b-a) > 1) {
        sort(x, off, s);
    }
    if ((s = d-c) > 1) {
        sort(x, n-s, s);
    }
}
Exemple #16
0
/* ********************************************************
   recursive multikey quicksort from Bentley-Sedgewick
   stops when text_depth reaches Shallow_depth_limit 
   that is when we have found that the current set of strings
   have Shallow_limit chars in common
   ******************************************************** */
static void shallow_mkq(Int32 *a, int n, UChar *text_depth)
{
  __inline__ void vecswap2(Int32 *a, Int32 *b, int n);
  int d, r, partval;
  Int32 *pa, *pb, *pc, *pd, *pl, *pm, *pn, t;
  UChar *next_depth;

  // ---- On small arrays use insertions sort
  if (n < Mk_qs_thresh) {
    shallow_inssort_lcp(a, n, text_depth);
    return;
  }

  // ----------- choose pivot --------------
 repeat:
  pl = a;
  pm = a + (n/2);
  pn = a + (n-1);
  if (n > 30) { // On big arrays, pseudomedian of 9
    d = (n/8);
    pl = med3(pl, pl+d, pl+2*d);
    pm = med3(pm-d, pm, pm+d);
    pn = med3(pn-2*d, pn-d, pn);
  }
  pm = med3(pl, pm, pn);
  swap2(a, pm);
  partval = ptr2char(a);
  pa = pb = a + 1;
  pc = pd = a + n-1;
  // -------- partition -----------------
  for (;;) {
    while (pb <= pc && (r = ptr2char(pb)-partval) <= 0) {
      if (r == 0) { swap2(pa, pb); pa++; }
      pb++;
    }
    while (pb <= pc && (r = ptr2char(pc)-partval) >= 0) {
      if (r == 0) { swap2(pc, pd); pd--; }
      pc--;
    }
    if (pb > pc) break;
    swap2(pb, pc);
    pb++;
    pc--;
  }

#if UNROLL
  if(pa>pd) {
    // all values were equal to partval: make it simpler
    if( (next_depth = text_depth+1) >= Shallow_text_limit) {
      helped_sort(a, n, next_depth-Text, Shallow_limit);
      return;
    }
    else {
      text_depth = next_depth;
      goto repeat;
    }
  }
#endif
  // partition a[] into the values smaller, equal, and larger that partval
  pn = a + n;
  r = min(pa-a, pb-pa);    vecswap2(a,  pb-r, r);
  r = min(pd-pc, pn-pd-1); vecswap2(pb, pn-r, r);
  // --- sort smaller strings -------
  if ((r = pb-pa) > 1)
    shallow_mkq(a, r, text_depth);
  // --- sort strings starting with partval -----
  if( (next_depth = text_depth+1) < Shallow_text_limit)
    shallow_mkq(a + r, pa-pd+n-1, next_depth);
  else 
    helped_sort(a + r, pa-pd+n-1, next_depth-Text, Shallow_limit);
  if ((r = pd-pc) > 1)
    shallow_mkq(a + n-r, r, text_depth);
}
/*
 * simple approach for now; a better median-finding
 * may be preferable
 */
static T choose_pivot(T *low, T *high)
{
	return med3(*low, *high, low[(high-low)/2UL]);
}
Exemple #18
0
void
yaffs_qsort(void *aa, size_t n, size_t es,
	int (*cmp)(const void *, const void *))
{
	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
	int d, r, swaptype, swap_cnt;
	register char *a = aa;

loop:	SWAPINIT(a, es);
	swap_cnt = 0;
	if (n < 7) {
		for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
			     pl -= es)
				yswap(pl, pl - es);
		return;
	}
	pm = (char *)a + (n / 2) * es;
	if (n > 7) {
		pl = (char *)a;
		pn = (char *)a + (n - 1) * es;
		if (n > 40) {
			d = (n / 8) * es;
			pl = med3(pl, pl + d, pl + 2 * d, cmp);
			pm = med3(pm - d, pm, pm + d, cmp);
			pn = med3(pn - 2 * d, pn - d, pn, cmp);
		}
		pm = med3(pl, pm, pn, cmp);
	}
	yswap(a, pm);
	pa = pb = (char *)a + es;

	pc = pd = (char *)a + (n - 1) * es;
	for (;;) {
		while (pb <= pc && (r = cmp(pb, a)) <= 0) {
			if (r == 0) {
				swap_cnt = 1;
				yswap(pa, pb);
				pa += es;
			}
			pb += es;
		}
		while (pb <= pc && (r = cmp(pc, a)) >= 0) {
			if (r == 0) {
				swap_cnt = 1;
				yswap(pc, pd);
				pd -= es;
			}
			pc -= es;
		}
		if (pb > pc)
			break;
		yswap(pb, pc);
		swap_cnt = 1;
		pb += es;
		pc -= es;
	}
	if (swap_cnt == 0) {  /* Switch to insertion sort */
		for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
			     pl -= es)
				yswap(pl, pl - es);
		return;
	}

	pn = (char *)a + n * es;
	r = min(pa - (char *)a, pb - pa);
	vecswap(a, pb - r, r);
	r = min((long)(pd - pc), (long)(pn - pd - es));
	vecswap(pb, pn - r, r);
	r = pb - pa;
	if (r > es)
		yaffs_qsort(a, r / es, es, cmp);
	r = pd - pc;
	if (r > es) {
		/* Iterate rather than recurse to save stack space */
		a = pn - r;
		n = r / es;
		goto loop;
	}
/*		yaffs_qsort(pn - r, r / es, es, cmp);*/
}
Exemple #19
0
	/* Subroutine for sort_split, algorithm by Bentley & McIlroy.*/
	int choose_pivot(const int_iter &p, int64_t n) {
	   int_iter pl, pm, pn;
	   int64_t s;
	   
	   pm=p+(n>>1);                 /* small arrays, middle element.*/
	   if (n>7) {
		  pl=p;
		  pn=p+n-1;
		  if (n>40) {               /* big arrays, pseudomedian of 9.*/
			 s=n>>3;
			 pl=med3(pl, pl+s, pl+s+s);
			 pm=med3(pm-s, pm, pm+s);
			 pn=med3(pn-s-s, pn-s, pn);
		  }
		  pm=med3(pl, pm, pn);      /* midsize arrays, median of 3.*/
	   }
	   return key(pm);
	}

	/* Sorting routine called for each unsorted group. Sorts the array of integers
	   (suffix numbers) of length n starting at p. The algorithm is a ternary-split
	   quicksort taken from Bentley & McIlroy, "Engineering a Sort Function",
	   Software -- Practice and Experience 23(11), 1249-1265 (November 1993). This
	   function is based on Program 7.*/
	void sort_split(const int_iter &p, int64_t n) {
	   int_iter pa, pb, pc, pd, pl, pm, pn;
	   uint64_t f, v;
	   int64_t  s, t;

	   if (n<7) {                   /* multi-selection sort smallest arrays.*/
void recast_qsort(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
{
	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
	int d, r, swaptype, swap_cnt;

loop:	
	SWAPINIT(a, es);
	swap_cnt = 0;
	if (n < 7) {
		for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
			for (pl = pm; 
				pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
				pl -= es)
				swap(pl, pl - es);
		return;
	}
	pm = (char *)a + (n / 2) * es;
	if (n > 7) {
		pl = (char *)a;
		pn = (char *)a + (n - 1) * es;
		if (n > 40) {
			d = (n / 8) * es;
			pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
			pm = med3(pm - d, pm, pm + d, cmp, thunk);
			pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
		}
		pm = med3(pl, pm, pn, cmp, thunk);
	}
	swap((char *)a, pm);
	pa = pb = (char *)a + es;

	pc = pd = (char *)a + (n - 1) * es;
	for (;;) {
		while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) {
			if (r == 0) {
				swap_cnt = 1;
				swap(pa, pb);
				pa += es;
			}
			pb += es;
		}
		while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) {
			if (r == 0) {
				swap_cnt = 1;
				swap(pc, pd);
				pd -= es;
			}
			pc -= es;
		}
		if (pb > pc)
			break;
		swap(pb, pc);
		swap_cnt = 1;
		pb += es;
		pc -= es;
	}
	if (swap_cnt == 0) {  /* Switch to insertion sort */
		for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
			for (pl = pm; 
				pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
				pl -= es)
				swap(pl, pl - es);
		return;
	}

	pn = (char *)a + n * es;
	r = min(pa - (char *)a, pb - pa);
	vecswap((char *)a, pb - r, r);
	r = min(pd - pc, pn - pd - es);
	vecswap(pb, pn - r, r);
	if ((r = pb - pa) > es)
		recast_qsort(a, r / es, es, thunk, cmp);
	if ((r = pd - pc) > es) {
		/* Iterate rather than recurse to save stack space */
		a = pn - r;
		n = r / es;
		goto loop;
	}
}
Exemple #21
0
static void
_pqsort(void *a, size_t n, size_t es,
    int (*cmp) (const void *, const void *), void *lrange, void *rrange)
{
	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
	size_t d, r;
	int swaptype, cmp_result;

loop:	SWAPINIT(a, es);
	if (n < 7) {
		for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
			     pl -= es)
				swap(pl, pl - es);
		return;
	}
	pm = (char *) a + (n / 2) * es;
	if (n > 7) {
		pl = (char *) a;
		pn = (char *) a + (n - 1) * es;
		if (n > 40) {
			d = (n / 8) * es;
			pl = med3(pl, pl + d, pl + 2 * d, cmp);
			pm = med3(pm - d, pm, pm + d, cmp);
			pn = med3(pn - 2 * d, pn - d, pn, cmp);
		}
		pm = med3(pl, pm, pn, cmp);
	}
	swap(a, pm);
	pa = pb = (char *) a + es;

	pc = pd = (char *) a + (n - 1) * es;
	for (;;) {
		while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) {
			if (cmp_result == 0) {
				swap(pa, pb);
				pa += es;
			}
			pb += es;
		}
		while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) {
			if (cmp_result == 0) {
				swap(pc, pd);
				pd -= es;
			}
			pc -= es;
		}
		if (pb > pc)
			break;
		swap(pb, pc);
		pb += es;
		pc -= es;
	}

	pn = (char *) a + n * es;
	r = min(pa - (char *) a, pb - pa);
	vecswap(a, pb - r, r);
	r = min((size_t)(pd - pc), pn - pd - es);
	vecswap(pb, pn - r, r);
	if ((r = pb - pa) > es) {
                void *_l = a, *_r = ((unsigned char*)a)+r-1;
                if (!((lrange < _l && rrange < _l) ||
                    (lrange > _r && rrange > _r)))
		    _pqsort(a, r / es, es, cmp, lrange, rrange);
        }
	if ((r = pd - pc) > es) {
                void *_l, *_r;

		/* Iterate rather than recurse to save stack space */
		a = pn - r;
		n = r / es;

                _l = a;
                _r = ((unsigned char*)a)+r-1;
                if (!((lrange < _l && rrange < _l) ||
                    (lrange > _r && rrange > _r)))
		    goto loop;
	}
/*		qsort(pn - r, r / es, es, cmp);*/
}