Go to the documentation of this file.
19 #ifndef CSNIP_QSORT_STACKSZ
21 #define CSNIP_QSORT_STACKSZ 64
24 #ifndef CSNIP_QSORT_SLIMIT
30 #define CSNIP_QSORT_SLIMIT 24
31 #elif CSNIP_QSORT_SLIMIT < 3
35 #error "CSNIP_QSORT_SLIMIT must be 3 or larger."
60 #define csnip_Qsort_median3_pivot(u, v, au_lessthan_av, swap_au_av, beg, end) \
66 const size_t csnip_qs_mid = beg + (end - beg)/2; \
70 if (au_lessthan_av) { \
75 if (au_lessthan_av) { \
86 if (au_lessthan_av) { \
130 #define csnip_Qsort_partition(u, v, au_lessthan_av, swap_au_av, beg, end, result) \
135 size_t csnip__qs_lo = beg; \
136 size_t csnip__qs_hi = end; \
143 } while (au_lessthan_av); \
151 } while (au_lessthan_av); \
155 if (csnip__qs_hi <= csnip__qs_lo) \
169 (result) = csnip__qs_hi; \
190 #define csnip_Qsort(u, v, au_lessthan_av, swap_au_av, N) \
193 int csnip_qs_n = 0; \
194 size_t csnip_qs_sbeg[CSNIP_QSORT_STACKSZ]; \
195 size_t csnip_qs_send[CSNIP_QSORT_STACKSZ]; \
196 if ((N) > CSNIP_QSORT_SLIMIT) { \
198 csnip_qs_sbeg[0] = 0; \
199 csnip_qs_send[0] = (N); \
203 while(csnip_qs_n > 0) { \
205 const size_t csnip_qs_beg = csnip_qs_sbeg[csnip_qs_n]; \
206 const size_t csnip_qs_end = csnip_qs_send[csnip_qs_n]; \
209 csnip_Qsort_median3_pivot(u, v, au_lessthan_av, swap_au_av, \
210 csnip_qs_beg, csnip_qs_end); \
214 csnip_Qsort_partition(u, v, au_lessthan_av, swap_au_av, \
215 csnip_qs_beg, csnip_qs_end, csnip_p); \
218 const size_t csnip_d1 = csnip_p - 1 - csnip_qs_beg; \
219 const size_t csnip_d2 = csnip_qs_end - csnip_p - 1; \
220 if (csnip_d1 > csnip_d2) { \
221 if (csnip_d1 > CSNIP_QSORT_SLIMIT) { \
222 csnip_qs_sbeg[csnip_qs_n] = csnip_qs_beg; \
223 csnip_qs_send[csnip_qs_n++] = csnip_p; \
224 if (csnip_d2 > CSNIP_QSORT_SLIMIT) { \
225 csnip_qs_sbeg[csnip_qs_n] = \
227 csnip_qs_send[csnip_qs_n++] = \
232 if (csnip_d2 > CSNIP_QSORT_SLIMIT) { \
233 csnip_qs_sbeg[csnip_qs_n] = \
235 csnip_qs_send[csnip_qs_n++] = \
237 if (csnip_d1 > CSNIP_QSORT_SLIMIT) { \
238 csnip_qs_sbeg[csnip_qs_n] = \
240 csnip_qs_send[csnip_qs_n++] = \
252 if (CSNIP_QSORT_SLIMIT > 1) { \
253 static const size_t csnip_gs[] = {1}; \
254 csnip_ShellsortGS(u, v, au_lessthan_av, \
255 swap_au_av, N, csnip_Static_len(csnip_gs), \
261 #ifndef CSNIP_HEAPSORT_K
263 #define CSNIP_HEAPSORT_K 2
283 #define csnip_Heapsort(u, v, au_lessthan_av, swap_au_av, N) \
287 csnip_heap_Heapify(v, u, au_lessthan_av, swap_au_av, \
288 CSNIP_HEAPSORT_K, N); \
289 size_t csnip__heapsort_i = (N) - 1; \
292 size_t u = 0, v = csnip__heapsort_i; \
295 if (csnip__heapsort_i <= 1) \
297 csnip_heap_SiftDown(v, u, \
298 au_lessthan_av, swap_au_av, \
299 CSNIP_HEAPSORT_K, csnip__heapsort_i, 0); \
300 --csnip__heapsort_i; \
324 #define csnip_Shellsort(u, v, au_lessthan_av, swap_au_av, N) \
326 int csnip_gap = ((N) > 4 ? (N) / 4 : 1); \
327 while (csnip_gap > 0) { \
329 for (csnip_j = csnip_gap; csnip_j < (N); ++csnip_j) { \
330 int u = csnip_j, v = csnip_j - csnip_gap; \
331 while (v >= 0 && (au_lessthan_av)) { \
339 if (csnip_gap == 2) \
341 csnip_gap = 4*csnip_gap / 9; \
351 #define csnip_ShellsortGS(u, v, au_lessthan_av, swap_au_av, N, nGaps, gapSeq) \
354 while (csnip_gi < (int)(nGaps)) { \
355 const int csnip_gap = (gapSeq)[csnip_gi]; \
357 for (csnip_j = csnip_gap; csnip_j < (N); ++csnip_j) { \
358 int u = csnip_j, v = csnip_j - csnip_gap; \
359 while (v >= 0 && (au_lessthan_av)) { \
385 #define csnip_IsSorted(u, v, au_lessthan_av, N, ret) \
390 const int v = u - 1; \
391 if (au_lessthan_av) { \
414 #define CSNIP_SORT_DECL_FUNCS(scope, prefix, gen_args) \
415 scope void prefix ## qsort(csnip_pp_list_##gen_args) \
416 scope void prefix ## heapsort(csnip_pp_list_##gen_args) \
417 scope void prefix ## shellsort(csnip_pp_list_##gen_args) \
418 scope int prefix ## is_sorted(csnip_pp_list_##gen_args)
446 #define CSNIP_SORT_DEF_FUNCS(scope, prefix, gen_args, \
447 u, v, au_lessthan_av, swap_au_av, N) \
449 scope void prefix ## qsort(csnip_pp_list_##gen_args) \
451 csnip_Qsort(u, v, au_lessthan_av, swap_au_av, N); \
454 scope void prefix ## heapsort(csnip_pp_list_##gen_args) \
456 csnip_Heapsort(u, v, au_lessthan_av, swap_au_av, N); \
459 scope void prefix ## shellsort(csnip_pp_list_##gen_args) \
461 csnip_Shellsort(u, v, au_lessthan_av, swap_au_av, N); \
464 scope int prefix ## is_sorted(csnip_pp_list_##gen_args) \
467 csnip_IsSorted(u, v, au_lessthan_av, N, ret); \
475 #if defined(CSNIP_SHORT_NAMES) && !defined(CSNIP_SORT_HAVE_SHORT_NAMES)
476 #define Qsort csnip_Qsort
477 #define Heapsort csnip_Heapsort
478 #define Shellsort csnip_Shellsort
479 #define IsSorted csnip_IsSorted
480 #define CSNIP_SORT_HAVE_SHORT_NAMES