예제 #1
0
static void ssort1(string x[], int n, int depth)
{   int    a, b, c, d, r, v;
    if (n <= 1)
        return;
    a = rand() % n;
    swap(0, a);
    v = i2c(0);
    a = b = 1;
    c = d = n-1;
    for (;;) {
        while (b <= c && (r = i2c(b)-v) <= 0) {
            if (r == 0) { swap(a, b); a++; }
            b++;
        }
        while (b <= c && (r = i2c(c)-v) >= 0) {
            if (r == 0) { swap(c, d); d--; }
            c--;
        }
        if (b > c) break;
        swap(b, c);
        b++;
        c--;
    }
    r = min(a, b-a);     vecswap(0, b-r, r, x);
    r = min(d-c, n-d-1); vecswap(b, n-r, r, x);
    r = b-a; ssort1(x, r, depth);
    if (i2c(r) != 0)
        ssort1(x + r, a + n-d-1, depth+1);
    r = d-c; ssort1(x + n-r, r, depth);
}
예제 #2
0
void ssort1(char *x[], int n, int depth,int* index)
{   
	int    a, b, c, d, r, v;
    if (n <= 1)
        return;
        
    /// Choosing the pivot
    //a = rand() % n;
    a=0;
    /// /////////////////
    
    swap(0, a);
    swapIndex(0,a);
    v = i2c(0);
    a = b = 1;
    c = d = n-1;
    
    
    for (;;) 
    {
        while (b <= c && (r = i2c(b)-v) <= 0) {
            if (r == 0) { swap(a, b); swapIndex(a,b);a++; }
            b++;
        }
        while (b <= c && (r = i2c(c)-v) >= 0) {
            if (r == 0) { swap(c, d); swapIndex(c,d);d--; }
            c--;
        }

        if (b > c) break;
        swap(b, c);
        swapIndex(b,c);
        b++;
        c--;
    }
    r = min(a, b-a);
    vecswap(0, b-r, r, x);
    vecswapIndex(0, b-r, r, index);
    r = min(d-c, n-d-1); 
    vecswap(b, n-r, r, x);
    vecswapIndex(b, n-r, r, index);
    r = b-a; 
     ssort1(x, r, depth,index);
    if (i2c(r) != 0)
        ssort1(x + r, a + n-d-1, depth+1,index+r);
    r = d-c; 
    ssort1(x + n-r, r, depth,index+ n-r);
}
예제 #3
0
파일: math.c 프로젝트: JamesLinus/inferno
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);
}
예제 #4
0
Uint *
quickSortMultikey (void *space, void* toSort, Uint size, 
 					Uint (*cmp)(Uint, Uint, Uint, void *, void*),
					Uint sentinel, void *info) 
{
  	Sint a, b, c, d, v, n, r;
	Uint *sorted = NULL, offset;
	Uint depth = 0;
	Stack stack;
	
	
	if (size == 0) return NULL;

	sorted = ALLOCMEMORY(space, NULL, Uint, size);
	if (size<=1) {
      sorted[0]=0;
    }
    
    for (r=0; r < size; r++) sorted[r]=r;
	initStack(space, &stack, 100);	
	n = size;
	offset=0;
	
	while (1) {
		a = rand() % n;
		SWAPUINT(sorted, offset, a+offset);
		v = sorted[offset];
		a = b = 1;
		c = d = n-1;
	
	  	for(;;) {
	    
		  	while(b<=c&&((r=cmp(sorted[b+offset],v,depth,toSort,info))==2||r==0))
			{
		  	
			  	if (r==0) {
		  			SWAPUINT(sorted, a+offset, b+offset);
					a++;
		  		}
		  		b++;
			}
			while(b<=c&&((r=cmp(sorted[c+offset],v,depth,toSort,info))==1||r==0)) 
			{
		  		
		  
			  	if (r==0) {
		  			SWAPUINT(sorted, c+offset, d+offset);
					d--;
		  		}
		  		c--;
			}
			if (b > c) break;
			SWAPUINT(sorted, b+offset, c+offset);
			b++;
			c--;
		}	
		r = MIN(a, (b-a));
		vecswap(offset, (b-r)+offset, r, sorted);
		r = MIN((d-c), (n-d-1));
		vecswap(b+offset, (n-r)+offset, r, sorted);
		/*sort lesser*/
		r = b-a;
		if (r > 1) {
		
		    stackpush(space, &stack, offset);
			stackpush(space, &stack, r);
			stackpush(space, &stack, depth);
		}
		/*sort equal*/
		if ((a+n-d-1) > 1 && cmp(sorted[r+offset], sentinel, depth, toSort, info) != 0)
		/*if (r > 1 && sorted[r+offset]!=sentinel)*/
		{ 
	  		stackpush(space, &stack, r+offset);
			stackpush(space, &stack, (a+n-d-1));
			stackpush(space, &stack, depth+1);
		}
		/*sort greater*/
		r=d-c;
		if (r > 1) {
	
		    stackpush(space, &stack, (n-r)+offset);
			stackpush(space, &stack, r);
			stackpush(space, &stack, depth);
		}
		
		if (!stackisempty(&stack)) {
			depth = stackpop(&stack);
			n = stackpop(&stack);
			offset = stackpop(&stack);
		} else {
			break;
		}	
	}	 
	destructStack(space, &stack);	
   	return sorted;
}
예제 #5
0
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;
	}
}
예제 #6
0
파일: qsort.c 프로젝트: tempbottle/scilab
/*--------------------------------------------------------------------------*/
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;
    }
}
예제 #7
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);*/
}
예제 #8
0
파일: qsort.c 프로젝트: michalsc/AROS
	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);*/
}
예제 #9
0
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);*/
}
예제 #10
0
파일: sort.c 프로젝트: spundhir/RNA-Seq
Uint *
quickSortMultikey (void *space, void* toSort, Uint size, 
		   Uint (*cmp)(Uint, Uint, Uint, void *, void*),
		   Uint sentinel, void *info) 
{
  Sint a, b, c, d, v, n, r;
  TripleSint ins;
  Uint *sorted = NULL, offset;
  Uint depth = 0;
  VStack vstack;
	
	
  if (size == 0) return NULL;

  sorted = ALLOCMEMORY(space, NULL, Uint, size);
  if (size<=1) {
    sorted[0]=0;
  }
    
  for (r=0; r < size; r++) sorted[r]=r;	
  bl_vstackInit(&vstack, 100, sizeof(TripleSint));
  n = size;
  offset=0;
	
  while (1) {
    a = rand() % n;
    SWAPUINT(sorted, offset, a+offset);
    v = sorted[offset];
    a = b = 1;
    c = d = n-1;
	
    for(;;) {
	    
      while(b<=c&&((r=cmp(sorted[b+offset],v,depth,toSort,info))==2||r==0))
	{
		  	
	  if (r==0) {
	    SWAPUINT(sorted, a+offset, b+offset);
	    a++;
	  }
	  b++;
	}
      while(b<=c&&((r=cmp(sorted[c+offset],v,depth,toSort,info))==1||r==0)) 
	{
		  		
		  
	  if (r==0) {
	    SWAPUINT(sorted, c+offset, d+offset);
	    d--;
	  }
	  c--;
	}
      if (b > c) break;
      SWAPUINT(sorted, b+offset, c+offset);
      b++;
      c--;
    }	
    r = MIN(a, (b-a));
    vecswap(offset, (b-r)+offset, r, sorted);
    r = MIN((d-c), (n-d-1));
    vecswap(b+offset, (n-r)+offset, r, sorted);
    /*sort lesser*/
    r = b-a;
    if (r > 1) {
      ins.a = offset;
      ins.b = r;
      ins.c = depth;
      bl_vstackPush(&vstack, &ins);
    }
    /*sort equal*/
    if ((a+n-d-1) > 1 && cmp(sorted[r+offset], sentinel, depth, toSort, info) != 0)
      /*if (r > 1 && sorted[r+offset]!=sentinel)*/
      { 
	ins.a = r+offset;
	ins.b = (a+n-d-1);
	ins.c = depth+1;
	bl_vstackPush(&vstack, &ins);
      }
    /*sort greater*/
    r=d-c;
    if (r > 1) {
      ins.a = (n-r)+offset;
      ins.b = r;
      ins.c = depth;
      bl_vstackPush(&vstack, &ins);
    }
		
    if (!bl_vstackIsEmpty(&vstack)){
      ins = *((TripleSint *) bl_vstackPop(&vstack, NULL));
      offset = ins.a;
      r = ins.b;
      depth = ins.c;
    } else {
      break;
    }	
  }   
  bl_vstackDestruct(&vstack, NULL);
  return sorted;
}
예제 #11
0
파일: f-qsort.c 프로젝트: rgchris/ren-c
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);*/
}
예제 #12
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);
    }
}
예제 #13
0
파일: compress.c 프로젝트: xflouris/bpp
static void ssort1(char ** x, int n, int depth, int * oi)
{
  int a,b,c,d,r,v;

  if (n <= 1) return;

  a = rand() % n;

  SWAP(x[0], x[a]);
  if (oi)
    SWAP(oi[0], oi[a]);

  v = x[0][depth];

  a = b = 1;
  c = d = n-1;

  while (1)
  {
    while (b <= c && (r = x[b][depth]-v) <= 0)
    {
      if (r == 0)
      {
        SWAP(x[a], x[b]);
        if (oi)
          SWAP(oi[a], oi[b]);
        ++a;
      }
      ++b;
    }
    while (b <= c && (r = x[c][depth]-v) >= 0)
    {
      if (r == 0)
      {
        SWAP(x[c], x[d]);
        if (oi)
          SWAP(oi[c], oi[d]);
        --d;
      }
      --c;
    }
    if (b > c) break;
    SWAP(x[b], x[c]);
    if (oi)
      SWAP(oi[b], oi[c]);
    ++b; --c;
  }

  r = MIN(a,b-a); vecswap(0,b-r,r,x,oi);
  r = MIN(d-c,n-d-1); vecswap(b,n-r,r,x,oi);
  r = b-a; ssort1(x,r,depth,oi);

  if (x[r][depth] != 0)
  {
    if (oi)
      ssort1 (x + r, a + n - d - 1, depth + 1, oi + r);
    else
      ssort1 (x + r, a + n - d - 1, depth + 1, NULL);

  }

    r = d - c; 
    if (oi)
      ssort1(x+n-r,r,depth,oi+n-r);
    else
      ssort1(x+n-r,r,depth,NULL);
}
예제 #14
0
int cg(
  int n,
  double* x,
  double* pfx,
  lbfgs_evaluate_t evaluate,
  lbfgs_progress_t progress,
  void* instance,
  const lbfgs_parameter_t* _param
) {
  static const double RHO = 0.01;
  static const double SIG = 0.5;
  static const double INT = 0.1;
  static const double EXT = 3.0;
  static const double RATIO = 100.0;

  int ret;
  int k, ls_count, ls_success, ls_failed = 0, n_evaluate = 0;
  lbfgs_parameter_t param = (_param) ? (*_param) : default_param;
  double f0, f1, f2 = 0.0, f3, d1, d2, d3, z1, z2 = 0.0, z3, limit, A, B, C;
  double xnorm, gnorm, rate;
  double* df0, *df1, *df2, *s, *x0;
  double* pf = 0;

  if (progress == 0) {
    progress = default_lbfgs_progress;
  }

  if (n <= 0) {
    return LBFGSERR_INVALID_N;
  }
  if (param.epsilon < 0.0) {
    return LBFGSERR_INVALID_EPSILON;
  }
  if (param.past < 0) {
    return LBFGSERR_INVALID_TESTPERIOD;
  }
  if (param.delta < 0.0) {
    return LBFGSERR_INVALID_DELTA;
  }
  if (param.max_linesearch <= 0) {
    return LBFGSERR_INVALID_MAXLINESEARCH;
  }

  df0 = vecalloc(n);
  df1 = vecalloc(n);
  df2 = vecalloc(n);
  s = vecalloc(n);
  x0 = vecalloc(n);

  if (param.past > 0) {
    pf = vecalloc((size_t)param.past);
  }

  f1 = evaluate(instance, n, x, df1, 0);
  n_evaluate++;

  if (pf) {
    pf[0] = f1;
  }

  vec2norm(&xnorm, x, n);
  vec2norm(&gnorm, df1, n);
  if (xnorm < 1.0) {
    xnorm = 1.0;
  }
  if (gnorm / xnorm <= param.epsilon) {
    ret = LBFGS_ALREADY_MINIMIZED;
    goto cg_exit;
  }

  vecncpy(s, df1, n);
  vecdot(&d1, s, s, n);
  d1 = -d1;
  /**
  * Compute the initial step z1:
  */
  z1 = 1.0 / (1.0 - d1);

  k = 1;
  for (;;) {
    /* Store the current position and gradient vectors. */
    f0 = f1;
    veccpy(x0, x, n);
    veccpy(df0, df1, n);

    /* update x using current step: x=x+z1*s */
    vecadd(x, s, z1, n);

    f2 = evaluate(instance, n, x, df2, 0);
    n_evaluate++;

    vecdot(&d2, df2, s, n);
    /* set point 3 equal to point 1 */
    f3 = f1;
    d3 = d1;
    z3 = -z1;

    /* begin line search */
    ls_success = 0;
    ls_count = 0;
    limit = -1.0;
    for (;;) {
      while (f2 > f1 + RHO * z1 * d1 || d2 > -SIG * d1) {
        limit = z1;
        if (f2 > f1) {
          /* quadratic fit */
          z2 = z3 - (0.5 * d3 * z3 * z3) / (d3 * z3 + f2 - f3);
        } else {
          /* cubic fit */
          A = 6 * (f2 - f3) / z3 + 3 * (d2 + d3);
          B = 3 * (f3 - f2) - z3 * (d3 + 2 * d2);
          z2 = (sqrt(B * B - A * d2 * z3 * z3) - B) / A;
        }

        if (isinf(z2) || isnan(z2)) {
          /* if we had a numerical problem then bisect */
          z2 = z3 / 2.0;
        }

        /* don't accept too close to limits */
        z2 = max2(min2(z2, INT* z3), (1.0 - INT) * z3);
        /* update step and x */
        z1 = z1 + z2;
        vecadd(x, s, z2, n);

        f2 = evaluate(instance, n, x, df2, 0);
        n_evaluate++;
        ls_count++;

        vecdot(&d2, df2, s, n);
        z3 = z3 - z2;
      }

      if (f2 > f1 + z1 * RHO * d1 || d2 > -SIG * d1) {
        /* a line search failure */
        break;
      } else if (d2 > SIG * d1) {
        /* a line search success */
        ls_success = 1;
        break;
      } else if (ls_count >= param.max_linesearch) {
        ret = LBFGSERR_MAXIMUMLINESEARCH;
        goto cg_exit;
      }

      /* cubic extrapolation */
      A = 6.0 * (f2 - f3) / z3 + 3.0 * (d2 + d3);
      B = 3.0 * (f3 - f2) - z3 * (d3 + 2 * d2);
      z2 = -d2 * z3 * z3 / (B + sqrt(B * B - A * d2 * z3 * z3));
      /* adjust current step z2 for many cases */
      if (isnan(z2) || isinf(z2) || z2 < 0.0) {
        if (limit < -0.5) {
          z2 = z1 * (EXT - 1.0);
        } else {
          z2 = (limit - z1) / 2.0;
        }
      } else if (limit > -0.5 && z2 + z1 > limit) {
        z2 = (limit - z1) / 2.0;
      } else if (limit < -0.5 && z2 + z1 > z1 * EXT) {
        z2 = z1 * (EXT - 1.0);
      } else if (z2 < -z3 * INT) {
        z2 = -z3 * INT;
      } else if (limit > -0.5 && z2 < (limit - z1) * (1.0 - INT)) {
        z2 = (limit - z1) * (1.0 - INT);
      }

      /* set point 3 equal to point 2 */
      f3 = f2;
      d3 = d2;
      z3 = -z2;

      z1 = z1 + z2;
      vecadd(x, s, z2, n);

      f2 = evaluate(instance, n, x, df2, 0);
      n_evaluate++;
      ls_count++;

      vecdot(&d2, df2, s, n);
    }

    if (ls_success) {
      vec2norm(&xnorm, x, n);
      vec2norm(&gnorm, df2, n);
      if ((ret = progress(instance, n, x, df2, f2, xnorm, gnorm, z2, k, n_evaluate)) != 0) {
        ret = LBFGSERR_CANCELED;
        break;
      }
      if (xnorm < 1.0) {
        xnorm = 1.0;
      }
      if (gnorm / xnorm <= param.epsilon) {
        ret = LBFGS_CONVERGENCE;
        break;
      }

      if (pf) {
        if (param.past <= k) {
          rate = (pf[k % param.past] - f2) / f2;
          if (rate < param.delta) {
            ret = LBFGS_CONVERGENCE_DELTA;
            break;
          }
        }
        pf[k % param.past] = f2;
      }

      if (param.max_iterations != 0 && param.max_iterations < k + 1) {
        ret = LBFGSERR_MAXIMUMITERATION;
        break;
      }
      k++;


      f1 = f2;
      /**
      * Polack-Ribiere direction
      * s = (df2'*df2-df1'*df2)/(df1'*df1)*s - df2
      */
      vecdot(&A, df2, df2, n);
      vecdot(&B, df1, df2, n);
      vecdot(&C, df1, df1, n);
      vecscale(s, (A - B) / C, n);
      vecadd(s, df2, -1.0, n);

      vecswap(df1, df2, n);
      vecdot(&d2, df1, s, n);

      if (d2 > 0) {
        vecncpy(s, df1, n);
        vecdot(&d2, s, s, n);
        d2 = -d2;
      }

      z1 = z1 * min2(RATIO, d1 / (d2 - DBL_MIN));
      d1 = d2;
      ls_failed = 0;
    } else {
      /* restore previous point */
      f1 = f0;
      veccpy(x, x0, n);
      veccpy(df1, df0, n);

      if (ls_failed) {
        /* line search failed twice */
        ret = LBFGSERR_LINE_SEARCH_FAILED;
        break;
      }

      vecswap(df1, df2, n);
      vecncpy(s, df1, n);/* try steepest */
      vecdot(&d1, s, s, n);
      d1 = -d1;
      z1 = 1.0 / (1.0 - d1);
      ls_failed = 1;
    }
  }

cg_exit:
  if (pfx) {
    *pfx = f2;
  }

  vecfree(pf);
  vecfree(x0);
  vecfree(s);
  vecfree(df2);
  vecfree(df1);
  vecfree(df0);
  return ret;
}
예제 #15
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);*/
}
예제 #16
0
파일: pqsort.c 프로젝트: Dean1987/LES_DOC
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);*/
}