int sradixsort(const u_char **a, int n, const u_char *tab, u_int endch) { const u_char *tr, **ta; int c; u_char tr0[256]; SETUP; if (n < THRESHOLD) simplesort(a, n, 0, tr, endch); else { if ((ta = malloc(n * sizeof(a))) == NULL) return (-1); r_sort_b(a, ta, n, 0, tr, endch); free(ta); } return (0); }
/* Stable sort, requiring additional memory. */ static void r_sort_b(u_char const **a, u_char const **ta, int n, int i, u_char const *tr, u_int endch) { static int count[256]; static u_int nc; static u_int bmin; u_int c; u_char const **ak, **ai; stack s[512], *sp, *sp0, *sp1, temp; u_char const **top[256]; int *cp; u_int bigc; sp = s; push(a, n, i); while (!empty(s)) { pop(a, n, i); if (n < THRESHOLD) { simplesort(a, n, i, tr, endch); continue; } if (nc == 0) { bmin = 255; for (ak = a + n; --ak >= a;) { c = tr[(*ak)[i]]; if (++count[c] == 1 && c != endch) { if (c < bmin) bmin = c; nc++; } } if (sp + nc > s + SIZE) { r_sort_b(a, ta, n, i, tr, endch); continue; } } sp0 = sp1 = sp; bigc = 2; if (endch == 0) { top[0] = ak = a + count[0]; count[0] = 0; } else { ak = a; top[255] = a + n; count[255] = 0; } for (cp = count + bmin; nc > 0; cp++) { while (*cp == 0) cp++; if ((c = *cp) > 1) { if (c > bigc) { bigc = c; sp1 = sp; } push(ak, c, i+1); } top[cp-count] = ak += c; *cp = 0; /* Reset count[]. */ nc--; } swap(*sp0, *sp1, temp); for (ak = ta + n, ai = a+n; ak > ta;) /* Copy to temp. */ *--ak = *--ai; for (ak = ta+n; --ak >= ta;) /* Deal to piles. */ *--top[tr[(*ak)[i]]] = *ak; } }