#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "lau.h"
#include "pcp.h"
#include "intsort.h"
/*
In-place integer sorting function based on algorithm by
R. Sedgewick.
BIG NOTE: 'vector' needs to have len+1 elements. The first len
elements are the numbers to be sorted. The last element is used
internally by sedgesort() function (which is called by ssort()) as a
'sentinel'.
*/
void intsort(int *vector, int len)
{
vector[len] = INT_MAX;
intsedgesort(vector, len);
}
/*
| void intheapsort (array, len)
| INTKEY_T array[];
| int len;
|
| Abstract: Sort array[0..len-1] into increasing order.
|
| Method: Heap-sort (ala Jon Bentley)
|
| Advantages:
|
| 1. Stable sorting method (doesn't spoil relative order between
| equal-key elements)
| 2. Worst case complexity is O (n log(n))
| 3. Method of choice when only the smallest n elemens are wanted
| and not a full ordering (use sift n times).
*/
void intheapsort (INTKEY_T array[], int len, int n)
{
register int i;
register INTKEY_T temp, *sa = array - 1;
int limit;
/*
| 'sa[]' is 'array[]' "shifted" one position to the left
| i.e. sa[i] == array[i - 1] (in particular: sa[1] == array[0])
| 'sa' has "Pascalish" indices and is thus more convenient
| for heap-sorting. An index i obeys the law:
| left_child (i) == 2i, right_child (i) == 2i + 1
| Note: we don't use a[-1] which is outside our range, we just
| fake an array that starts one address lower, so we can refer
| to its first element as a[1] (rather than as a[0])
*/
/* first step: make 'sa[]' a heap using intsiftdown len/2 times */
for (i = len / 2; i >= 1; i--)
intsiftdown (sa, i, len);
/* heapify n times, to reach partial order */
limit = 2;
if (len-n+1 > 2)
limit = len-n+1;
for (i = len; i >= limit; i--)
{
SWAP(sa[1], sa[i]);
intsiftdown (sa, 1, i - 1);
}
}
/*
| void intsiftdown (array, lower, upper)
| INTKEY_T array[];
| int lower, upper;
|
| Abstract:
| Assume array[] is a heap except array[lower] is not in order.
| Sift array[lower] down the heap as long as it is bigger than
| its two children nodes. Preserving the heap condition.
|
| Optimization: rather than swapping array[i] with the greater
| of its children within the loop, we save array[lower]
| before the loop, shift the inner values within the loop, and
| finally plug the saved value into its final location.
*/
void intsiftdown (INTKEY_T array[], int lower, int upper)
{
register int i = lower, c = lower;
register int lastindex = upper/2;
register INTKEY_T temp;
temp = array[i];
while (c <= lastindex) {
c = 2 * i; /* c = 2i is the left-child of i */
if (c + 1 <= upper && GT(array[c + 1], array[c]))
c++; /* c is the greatest child of i */
if (GE(temp, array[c])) break;
array[i] = array[c];
i = c;
}
array[i] = temp;
}
syntax highlighted by Code2HTML, v. 0.9.1