rlm@1: /* Sort.c -- Sort functions rlm@1: 2008-08-17 rlm@1: Igor Pavlov rlm@1: Public domain */ rlm@1: rlm@1: #include "Sort.h" rlm@1: rlm@1: #define HeapSortDown(p, k, size, temp) \ rlm@1: { for (;;) { \ rlm@1: UInt32 s = (k << 1); \ rlm@1: if (s > size) break; \ rlm@1: if (s < size && p[s + 1] > p[s]) s++; \ rlm@1: if (temp >= p[s]) break; \ rlm@1: p[k] = p[s]; k = s; \ rlm@1: } p[k] = temp; } rlm@1: rlm@1: void HeapSort(UInt32 *p, UInt32 size) rlm@1: { rlm@1: if (size <= 1) rlm@1: return; rlm@1: p--; rlm@1: { rlm@1: UInt32 i = size / 2; rlm@1: do rlm@1: { rlm@1: UInt32 temp = p[i]; rlm@1: UInt32 k = i; rlm@1: HeapSortDown(p, k, size, temp) rlm@1: } rlm@1: while (--i != 0); rlm@1: } rlm@1: /* rlm@1: do rlm@1: { rlm@1: UInt32 k = 1; rlm@1: UInt32 temp = p[size]; rlm@1: p[size--] = p[1]; rlm@1: HeapSortDown(p, k, size, temp) rlm@1: } rlm@1: while (size > 1); rlm@1: */ rlm@1: while (size > 3) rlm@1: { rlm@1: UInt32 temp = p[size]; rlm@1: UInt32 k = (p[3] > p[2]) ? 3 : 2; rlm@1: p[size--] = p[1]; rlm@1: p[1] = p[k]; rlm@1: HeapSortDown(p, k, size, temp) rlm@1: } rlm@1: { rlm@1: UInt32 temp = p[size]; rlm@1: p[size] = p[1]; rlm@1: if (size > 2 && p[2] < temp) rlm@1: { rlm@1: p[1] = p[2]; rlm@1: p[2] = temp; rlm@1: } rlm@1: else rlm@1: p[1] = temp; rlm@1: } rlm@1: } rlm@1: rlm@1: /* rlm@1: #define HeapSortRefDown(p, vals, n, size, temp) \ rlm@1: { UInt32 k = n; UInt32 val = vals[temp]; for (;;) { \ rlm@1: UInt32 s = (k << 1); \ rlm@1: if (s > size) break; \ rlm@1: if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ rlm@1: if (val >= vals[p[s]]) break; \ rlm@1: p[k] = p[s]; k = s; \ rlm@1: } p[k] = temp; } rlm@1: rlm@1: void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size) rlm@1: { rlm@1: if (size <= 1) rlm@1: return; rlm@1: p--; rlm@1: { rlm@1: UInt32 i = size / 2; rlm@1: do rlm@1: { rlm@1: UInt32 temp = p[i]; rlm@1: HeapSortRefDown(p, vals, i, size, temp); rlm@1: } rlm@1: while (--i != 0); rlm@1: } rlm@1: do rlm@1: { rlm@1: UInt32 temp = p[size]; rlm@1: p[size--] = p[1]; rlm@1: HeapSortRefDown(p, vals, 1, size, temp); rlm@1: } rlm@1: while (size > 1); rlm@1: } rlm@1: */