📄 iqsort.h
字号:
/*** Sorting stuff by Dann Corbit and Pete Filandr.** (dcorbit@connx.com and pfilandr@mindspring.com)** Use it however you like.*///// The insertion sort template is used for small partitions.// Insertion sort is stable.//template < class e_type >void insertion_sort(e_type * array, size_t nmemb){ e_type temp, *last, *first, *middle; if (nmemb > 1) { first = middle = 1 + array; last = nmemb - 1 + array; while (first != last) { ++first; if ((*(middle) > *(first))) { middle = first; } } if ((*(array) > *(middle))) { ((void) ((temp) = *(array), *(array) = *(middle), *(middle) = (temp))); } ++array; while (array != last) { first = array++; if ((*(first) > *(array))) { middle = array; temp = *middle; do { *middle-- = *first--; } while ((*(first) > *(&temp))); *middle = temp; } } }}//// The median estimate is used to choose pivots for the quicksort algorithm//template < class e_type >void median_estimate(e_type * array, size_t n){ e_type temp; long unsigned lu_seed = 123456789LU; const size_t k = ((lu_seed) = 69069 * (lu_seed) + 362437) % --n; ((void) ((temp) = *(array), *(array) = *(array + k), *(array + k) = (temp))); if ((*((array + 1)) > *((array)))) { (temp) = *(array + 1); if ((*((array + n)) > *((array)))) { *(array + 1) = *(array); if ((*(&(temp)) > *((array + n)))) { *(array) = *(array + n); *(array + n) = (temp); } else { *(array) = (temp); } } else { *(array + 1) = *(array + n); *(array + n) = (temp); } } else { if ((*((array)) > *((array + n)))) { if ((*((array + 1)) > *((array + n)))) { (temp) = *(array + 1); *(array + 1) = *(array + n); *(array + n) = *(array); *(array) = (temp); } else { ((void) (((temp)) = *((array)), *((array)) = *((array + n)), *((array + n)) = ((temp)))); } } }}//// This is the heart of the quick sort algorithm used here.// If the sort is going quadratic, we switch to heap sort.// If the partition is small, we switch to insertion sort.//template < class e_type >void qloop(e_type * array, size_t nmemb, size_t d){ e_type temp, *first, *last; while (nmemb > 50) { if (sorted(array, nmemb)) { return; } if (!d--) { heapsort(array, nmemb); return; } median_estimate(array, nmemb); first = 1 + array; last = nmemb - 1 + array; do { ++first; } while ((*(array) > *(first))); do { --last; } while ((*(last) > *(array))); while (last > first) { ((void) ((temp) = *(last), *(last) = *(first), *(first) = (temp))); do { ++first; } while ((*(array) > *(first))); do { --last; } while ((*(last) > *(array))); } ((void) ((temp) = *(array), *(array) = *(last), *(last) = (temp))); qloop(last + 1, nmemb - 1 + array - last, d); nmemb = last - array; } insertion_sort(array, nmemb);}//// This heap sort is better than average because it uses Lamont's heap.//template < class e_type >void heapsort(e_type * array, size_t nmemb){ size_t i, child, parent; e_type temp; if (nmemb > 1) { i = --nmemb / 2; do { { (parent) = (i); (temp) = (array)[(parent)]; (child) = (parent) * 2; while ((nmemb) > (child)) { if ((*((array) + (child) + 1) > *((array) + (child)))) { ++(child); } if ((*((array) + (child)) > *(&(temp)))) { (array)[(parent)] = (array)[(child)]; (parent) = (child); (child) *= 2; } else { --(child); break; } } if ((nmemb) == (child) && (*((array) + (child)) > *(&(temp)))) { (array)[(parent)] = (array)[(child)]; (parent) = (child); } (array)[(parent)] = (temp); } } while (i--); ((void) ((temp) = *(array), *(array) = *(array + nmemb), *(array + nmemb) = (temp))); for (--nmemb; nmemb; --nmemb) { { (parent) = (0); (temp) = (array)[(parent)]; (child) = (parent) * 2; while ((nmemb) > (child)) { if ((*((array) + (child) + 1) > *((array) + (child)))) { ++(child); } if ((*((array) + (child)) > *(&(temp)))) { (array)[(parent)] = (array)[(child)]; (parent) = (child); (child) *= 2; } else { --(child); break; } } if ((nmemb) == (child) && (*((array) + (child)) > *(&(temp)))) { (array)[(parent)] = (array)[(child)]; (parent) = (child); } (array)[(parent)] = (temp); } ((void) ((temp) = *(array), *(array) = *(array + nmemb), *(array + nmemb) = (temp))); } }}// // We use this to check to see if a partition is already sorted.// template < class e_type >int sorted(e_type * array, size_t nmemb){ for (--nmemb; nmemb; --nmemb) { if ((*(array) > *(array + 1))) { return 0; } ++array; } return 1;}// // We use this to check to see if a partition is already reverse-sorted.// template < class e_type >int rev_sorted(e_type * array, size_t nmemb){ for (--nmemb; nmemb; --nmemb) { if ((*(array + 1) > *(array))) { return 0; } ++array; } return 1;}// // We use this to reverse a reverse-sorted partition.// template < class e_type >void rev_array(e_type * array, size_t nmemb){ e_type temp, *end; for (end = array + nmemb - 1; end > array; ++array) { ((void) ((temp) = *(array), *(array) = *(end), *(end) = (temp))); --end; }}// // Introspective quick sort algorithm user entry point.// You do not need to directly call any other sorting template.// This sort will perform very well under all circumstances.// template < class e_type >void iqsort(e_type * array, size_t nmemb){ size_t d, n; if (nmemb > 1 && !sorted(array, nmemb)) { if (!rev_sorted(array, nmemb)) { n = nmemb / 4; d = 2; while (n) { ++d; n /= 2; } qloop(array, nmemb, 2 * d); } else { rev_array(array, nmemb); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -