void bubblesort(void *base, size_t nmemb, size_t size, int (*cmpfunc)(const void *, const void *)) { int swaptype; char *tmp1 = (char *)base; char *tmp2 = (char *)base + size; SWAPINIT(base, size); size_t i = 0; size_t n = nmemb; size_t nnew; do { nnew = 0; for (i = 1; i <= n - 1; i++) { tmp1 = (char *)base + (size * (i - 1)); tmp2 = (char *)base + (size * ((i - 1) + 1)); if (cmpfunc(tmp1, tmp2) > 0) { swap(tmp1, tmp2); nnew = i; } } n = nnew; } while (n > 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; } }
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);*/ }
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);*/ }
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);*/ }
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);*/ }
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);*/ }