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