void selection_sort(Item a[], int l, int r)
{
int i, j;
for (i = l; i < r; ++i)
{
int min = i;
for (j = i + 1; j <= r; ++j)
if (less(a[j], a[min])) min = j;
exch(a[i], a[min]);
}
}
void insertion_sort(Item a[], int l, int r)
{
int i;
/* find the minimun first to use as a sentinel */
for (i = l + 1; i <= r; ++i)
compexch(a[l], a[i]);
for (i = l + 2; i <= r; ++i)
{
int j = i;
Item v = a[i];
while (less(v, a[j - 1]))
{
a[j] = a[j - 1];
--j;
}
a[j] = v;
}
}
void bubble_sort(Item a[], int l, int r)
{
int i, j;
for (i = l; i < r; ++i)
for (j = r; j > i; --j)
compexch(a[j-1], a[j]);
}
1
2 3
4 6 9
8 12 18 27
16 24 36 54 81
)
/* increment sequence: 1 4 13 40 121 364 1093 3280 9841 ... */
void shell_sort(Item a[], int l, int r)
{
int i, j, h;
for (h = 1; h <= (r - l) / 9; h = 3 * h + 1) ;
for ( ; h > 0; h /= 3)
for (i = l + h; i <= r; ++i)
{
int j = i;
Item v = a[i];
while (j >= l + h && less(v, a[j - h]))
{
a[j] = a[j-h];
j -= h;
}
a[j] = v;
}
}
void sort(Item a[], int l, int r)
{
quick_sort(a, l, r);
/* refinement 1: insertion sort is efficient for the almost sorted
* file left by the prudent quick sort */
insertion_sort(a, l, r);
}
void quick_sort(Item a[], int l, int r)
{
int i, j;
stackinit();
push2(l, r);
while (!stackempty())
{
l = pop();
r = pop();
/* refinement 1: use cutoff for small subfiles to limit the number
* of small problems at deep recursion, thus to save a major part
* of recursive subroutine call overhead */
if (r-1 < M) continue;
partition(a, l, r, &i, &j);
/* refinement 2: use explicit pushdown stack to do tail-recursion
* removal, and sort small subfile first to reduce the maximum stack depth */
if (i-l > r-i) {
push2(l, i-1);
push2(i+1, r);
}
else {
push2(i+1, r);
push2(l, i-1);
}
}
}
void partition(Item a[], int l, int r, int *ii, int *jj)
{
int i,j, k, p, q;
Item v;
/* refinement 3: median-of-three(sampling) partitioning */
exch(a[(l+r)/2], a[r-1]);
compexch(a[l], a[r-1]);
compexch(a[l], a[r]);
/* the median is left at the right end to serve as the pivot */
compexch(a[r], a[r-1]);
v = a[r];
i = l-1;
j = r;
p = l-1;
q = r;
for (;;)
{
while (less(a[++i], v)) ; /* a[l] serves as sentinel */
while (less(v, a[--j])) ; /* a[r] serves as sentinel */
if (i >= j) break;
if (eq(a[i], v)) {
++p;
/* throw equals to the ends */
exch(a[p], a[i]);
if (eq(a[j], v)) {
--q;
/* throw equals to the ends */
exch(a[q], a[j]);
}
else {
/* a[j] will be processed in next loop */
++j;
}
}
else if (eq(v, a[j])) {
--q;
/* throw equals to the ends */
exch(a[q], a[j]);
/* a[i] will be processed in next loop */
--i;
}
else {
exch(a[i], a[j]);
}
}
/* crossing at an element equal to v */
if (i == j) {
exch(a[i+1], a[r]);
j = i-1;
i = i+2;
}
else {
exch(a[i], a[r]);
j = i-1;
i = i+1;
}
/* refinement 4: three-way partitioning */
/* move the equals from ends to middle */
/* move the lesses to the left subfile */
/* move the largers to the right subfile */
for (k = l ; k <= p; ++k, --j) exch(a[k], a[j]);
for (k = r-1; k >= q; --k, ++i) exch(a[k], a[i]);
*ii = i;
*jj = j;
}
void mergeAB(Item c[], Item a[], int N, Item b[], int M)
{
int i, j, k;
for (i = 0, j = 0, k = 0; ; ++k) {
if (i == N) break;
if (j == M) break;
/* c[k] = less(b[i], a[i]) ? b[i++] : a[j++]; */
/* keep stability in the assumption that a[] is before b[] in the
* original sequence */
c[k] = less(b[i], a[i]) ? b[i++] : a[j++];
}
if (i == N) {
for ( ; k < M + N; ++k) {
c[k] = b[j++];
}
}
else { /* j == M */
for ( ; k < M + N; ++k) {
c[k] = a[i++];
}
}
}
Item aux[maxN];
void merge_sortAB(Item a[], Item b[], int l, int r)
{
int m = (l + r) / 2;
if (r - 1 < 10) { /* improvement 1: cutoff for small subfiles */
insertion_sort(a, l, r);
return;
}
merge_sortAB(b, a, l, m);
merge_sortAB(b, a, m + 1, r);
mergeAB(a + l, b + l, m - l + 1, b + m + 1, r - m);
}
void merge_sort(Item a[], int l, int r)
{
int i;
/* improvement 2: merge data in a flip-flop manner between two arrays
* to eliminate the time taken to copy to the auxiliary array in
* every merging */
for (i = l; i <= r; ++i) aux[i] = a[j];
merge_sortAB(a, aux, l, r);
}
void heap_sort(Item a[], int l, int r)
{
int k, N = r - l + 1;
Item *pq = a + l - 1;
for (k = N/2; k >= 1; k--)
fixDown(pq, k, N);
while (N > 1) {
exch(pq[1], pq[N]);
fixDown(pq, 1, --N);
}
}
void fixDown(Item a[], int k, int N)
{
int i;
while (2 * k <= N) {
i = 2 * k;
if (i < N && less(a[i], a[i+1])) ++i;
if (!less(a[k], a[i])) break;
exch(a[k], a[j]);
k = i;
}
}
void counting_sort(int a[], int l, int r)
{
int i, j, cnt[M];
int b[maxN];
for (j = 0; j < M; ++j) cnt[j] = 0;
for (i = l; i <= r; ++i) ++cnt[a[i] + 1];
for (j = 1; j < M; ++j) cnt[j] += cnt[j - 1];
for (i = l; i <= r; ++i) b[cnt[a[i]]++] = a[i];
for (i = l; i <= r; ++i) a[i] = b[i];
}
#define bin(A) l+count[A]
#define digit(A, B) ... /* retrive the Bth digit of A */
void radixMSD(Item a[], int l, int r, int w)
{
int i, j, count[R+1];
if (w > bytesword) return;
/* cutoff for small file */
if (r-l <= M) {
insertion(a, l, r);
return;
}
for (j = 0; j < R; j++) count[j] = 0;
for (i = l; i <= r; i++)
count[digit(a[i], w) + 1]++;
for (j = 1; j < R; j++)
count[j] += count[j-1];
for (i = l; i <= r; i++)
aux[l+count[digit(a[i], w)]++] = a[i];
for (i = l; i <= r; i++) a[i] = aux[i];
radixMSD(a, l, bin(0)-1, w+1);
for (j = 0; j < R-1; j++)
radixMSD(a, bin(j), bin(j+1)-1, w+1);
}
#define ch(A) digit(A, D)
void quicksortX(Item a[], int l, int r, int D)
{
int i, j, k, p, q;
int v;
if (r-l <= M) {
insertion(a, l, r);
return;
}
v = ch(a[r]); i = l-1; j = r; p = l-1; q = r;
while (i < j)
{
while (ch(a[++i]) < v) ;
while (v < ch(a[--j])) if (j == l) break;
if (i > j) break;
exch(a[i], a[j]);
if (ch(a[i])==v) { p++; exch(a[p], a[i]); }
if (v==ch(a[j])) { q--; exch(a[j], a[q]); }
}
/* all are equal at digit D */
if (p == q)
{
if (v != END_OF_KEY) quicksortX(a, l, r, D+1);
return;
}
if (ch(a[i]) < v) i++;
for (k = l; k <= p; k++, j--) exch(a[k], a[j]);
for (k = r; k >= q; k--, i++) exch(a[k], a[i]);
quicksortX(a, l, j, D);
if ((i == r) && (ch(a[i]) == v)) i++;
if (v != END_OF_KEY) quicksortX(a, j+1, i-1, D+1);
quicksortX(a, i, r, D);
}
void radixLSD(Item a[], int l, int r)
{
int i, j, w, count[R+1];
for (w = bytesword-1; w >= 0; w--)
{
for (j = 0; j < R; j++) count[j] = 0;
for (i = l; i <= r; i++)
count[digit(a[i], w) + 1]++;
for (j = 1; j < R; j++)
count[j] += count[j-1];
for (i = l; i <= r; i++)
aux[count[digit(a[i], w)]++] = a[i];
for (i = l; i <= r; i++) a[i] = aux[i];
}
}
Definitions:
It is wonderful and neat solution.
However explanation through some sublink would more value it. Thanks
© Wangling. Powered by WordPress using the DePo Skinny Theme.
1 Comment