1370b324cSopenharmony_ci/* Sort.c -- Sort functions 2370b324cSopenharmony_ci2014-04-05 : Igor Pavlov : Public domain */ 3370b324cSopenharmony_ci 4370b324cSopenharmony_ci#include "Precomp.h" 5370b324cSopenharmony_ci 6370b324cSopenharmony_ci#include "Sort.h" 7370b324cSopenharmony_ci 8370b324cSopenharmony_ci#define HeapSortDown(p, k, size, temp) \ 9370b324cSopenharmony_ci { for (;;) { \ 10370b324cSopenharmony_ci size_t s = (k << 1); \ 11370b324cSopenharmony_ci if (s > size) break; \ 12370b324cSopenharmony_ci if (s < size && p[s + 1] > p[s]) s++; \ 13370b324cSopenharmony_ci if (temp >= p[s]) break; \ 14370b324cSopenharmony_ci p[k] = p[s]; k = s; \ 15370b324cSopenharmony_ci } p[k] = temp; } 16370b324cSopenharmony_ci 17370b324cSopenharmony_civoid HeapSort(UInt32 *p, size_t size) 18370b324cSopenharmony_ci{ 19370b324cSopenharmony_ci if (size <= 1) 20370b324cSopenharmony_ci return; 21370b324cSopenharmony_ci p--; 22370b324cSopenharmony_ci { 23370b324cSopenharmony_ci size_t i = size / 2; 24370b324cSopenharmony_ci do 25370b324cSopenharmony_ci { 26370b324cSopenharmony_ci UInt32 temp = p[i]; 27370b324cSopenharmony_ci size_t k = i; 28370b324cSopenharmony_ci HeapSortDown(p, k, size, temp) 29370b324cSopenharmony_ci } 30370b324cSopenharmony_ci while (--i != 0); 31370b324cSopenharmony_ci } 32370b324cSopenharmony_ci /* 33370b324cSopenharmony_ci do 34370b324cSopenharmony_ci { 35370b324cSopenharmony_ci size_t k = 1; 36370b324cSopenharmony_ci UInt32 temp = p[size]; 37370b324cSopenharmony_ci p[size--] = p[1]; 38370b324cSopenharmony_ci HeapSortDown(p, k, size, temp) 39370b324cSopenharmony_ci } 40370b324cSopenharmony_ci while (size > 1); 41370b324cSopenharmony_ci */ 42370b324cSopenharmony_ci while (size > 3) 43370b324cSopenharmony_ci { 44370b324cSopenharmony_ci UInt32 temp = p[size]; 45370b324cSopenharmony_ci size_t k = (p[3] > p[2]) ? 3 : 2; 46370b324cSopenharmony_ci p[size--] = p[1]; 47370b324cSopenharmony_ci p[1] = p[k]; 48370b324cSopenharmony_ci HeapSortDown(p, k, size, temp) 49370b324cSopenharmony_ci } 50370b324cSopenharmony_ci { 51370b324cSopenharmony_ci UInt32 temp = p[size]; 52370b324cSopenharmony_ci p[size] = p[1]; 53370b324cSopenharmony_ci if (size > 2 && p[2] < temp) 54370b324cSopenharmony_ci { 55370b324cSopenharmony_ci p[1] = p[2]; 56370b324cSopenharmony_ci p[2] = temp; 57370b324cSopenharmony_ci } 58370b324cSopenharmony_ci else 59370b324cSopenharmony_ci p[1] = temp; 60370b324cSopenharmony_ci } 61370b324cSopenharmony_ci} 62370b324cSopenharmony_ci 63370b324cSopenharmony_civoid HeapSort64(UInt64 *p, size_t size) 64370b324cSopenharmony_ci{ 65370b324cSopenharmony_ci if (size <= 1) 66370b324cSopenharmony_ci return; 67370b324cSopenharmony_ci p--; 68370b324cSopenharmony_ci { 69370b324cSopenharmony_ci size_t i = size / 2; 70370b324cSopenharmony_ci do 71370b324cSopenharmony_ci { 72370b324cSopenharmony_ci UInt64 temp = p[i]; 73370b324cSopenharmony_ci size_t k = i; 74370b324cSopenharmony_ci HeapSortDown(p, k, size, temp) 75370b324cSopenharmony_ci } 76370b324cSopenharmony_ci while (--i != 0); 77370b324cSopenharmony_ci } 78370b324cSopenharmony_ci /* 79370b324cSopenharmony_ci do 80370b324cSopenharmony_ci { 81370b324cSopenharmony_ci size_t k = 1; 82370b324cSopenharmony_ci UInt64 temp = p[size]; 83370b324cSopenharmony_ci p[size--] = p[1]; 84370b324cSopenharmony_ci HeapSortDown(p, k, size, temp) 85370b324cSopenharmony_ci } 86370b324cSopenharmony_ci while (size > 1); 87370b324cSopenharmony_ci */ 88370b324cSopenharmony_ci while (size > 3) 89370b324cSopenharmony_ci { 90370b324cSopenharmony_ci UInt64 temp = p[size]; 91370b324cSopenharmony_ci size_t k = (p[3] > p[2]) ? 3 : 2; 92370b324cSopenharmony_ci p[size--] = p[1]; 93370b324cSopenharmony_ci p[1] = p[k]; 94370b324cSopenharmony_ci HeapSortDown(p, k, size, temp) 95370b324cSopenharmony_ci } 96370b324cSopenharmony_ci { 97370b324cSopenharmony_ci UInt64 temp = p[size]; 98370b324cSopenharmony_ci p[size] = p[1]; 99370b324cSopenharmony_ci if (size > 2 && p[2] < temp) 100370b324cSopenharmony_ci { 101370b324cSopenharmony_ci p[1] = p[2]; 102370b324cSopenharmony_ci p[2] = temp; 103370b324cSopenharmony_ci } 104370b324cSopenharmony_ci else 105370b324cSopenharmony_ci p[1] = temp; 106370b324cSopenharmony_ci } 107370b324cSopenharmony_ci} 108370b324cSopenharmony_ci 109370b324cSopenharmony_ci/* 110370b324cSopenharmony_ci#define HeapSortRefDown(p, vals, n, size, temp) \ 111370b324cSopenharmony_ci { size_t k = n; UInt32 val = vals[temp]; for (;;) { \ 112370b324cSopenharmony_ci size_t s = (k << 1); \ 113370b324cSopenharmony_ci if (s > size) break; \ 114370b324cSopenharmony_ci if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ 115370b324cSopenharmony_ci if (val >= vals[p[s]]) break; \ 116370b324cSopenharmony_ci p[k] = p[s]; k = s; \ 117370b324cSopenharmony_ci } p[k] = temp; } 118370b324cSopenharmony_ci 119370b324cSopenharmony_civoid HeapSortRef(UInt32 *p, UInt32 *vals, size_t size) 120370b324cSopenharmony_ci{ 121370b324cSopenharmony_ci if (size <= 1) 122370b324cSopenharmony_ci return; 123370b324cSopenharmony_ci p--; 124370b324cSopenharmony_ci { 125370b324cSopenharmony_ci size_t i = size / 2; 126370b324cSopenharmony_ci do 127370b324cSopenharmony_ci { 128370b324cSopenharmony_ci UInt32 temp = p[i]; 129370b324cSopenharmony_ci HeapSortRefDown(p, vals, i, size, temp); 130370b324cSopenharmony_ci } 131370b324cSopenharmony_ci while (--i != 0); 132370b324cSopenharmony_ci } 133370b324cSopenharmony_ci do 134370b324cSopenharmony_ci { 135370b324cSopenharmony_ci UInt32 temp = p[size]; 136370b324cSopenharmony_ci p[size--] = p[1]; 137370b324cSopenharmony_ci HeapSortRefDown(p, vals, 1, size, temp); 138370b324cSopenharmony_ci } 139370b324cSopenharmony_ci while (size > 1); 140370b324cSopenharmony_ci} 141370b324cSopenharmony_ci*/ 142