1 /* A "counting" merge sort that avoids recursion */
3 #define N_DIGITS (sizeof (size_t) * 8)
6 add_digits (digit first, digit second, GCompareFunc func)
8 /* merge the two lists */
11 while (first && second) {
12 if (func (first->data, second->data) > 0) {
14 second = second->next;
19 pos = &((*pos)->next);
21 *pos = first ? first : second;
26 combine_digits (digit *digits, int max_digit, GCompareFunc func)
29 digit list = digits [0];
30 for (i = 1; i <= max_digit; ++i)
31 list = add_digits (digits [i], list, func);
36 increment (digit *digits, digit list, int max_digit, GCompareFunc func)
43 for (i = 0; digits [i]; i++) {
44 list = add_digits (digits [i], list, func);
46 if (i == N_DIGITS-1) /* Should _never_ happen, but if it does, we just devolve into quadratic ;-) */
50 return i > max_digit ? i : max_digit;
54 do_sort (digit list, GCompareFunc func)
57 digit digits [N_DIGITS]; /* 128 bytes on 32bit, 512 bytes on 64bit */
58 memset (digits, 0, sizeof digits);
60 while (list && list->next) {
61 digit next = list->next;
62 digit tail = next->next;
64 if (func (list->data, next->data) > 0) {
71 max_digit = increment (digits, list, max_digit, func);
76 max_digit = increment (digits, list, max_digit, func);
78 return combine_digits (digits, max_digit, func);