[go: up one dir, main page]

Menu

[897c37]: / mlib / lib / sort.lpc  Maximize  Restore  History

Download this file

95 lines (88 with data), 1.9 kB

/*
 * Quick 'n nasty heap sort routine.
 * Does an in-place sort on an array.
 * Sorts about 270 elements before eval-costing - this
 * could probably be increased.
 * will be fixed soon to work on key, value pairs.
 * Gandalf, '92.
 *
 * Call sort(arr, eltsize, compelt).
 * Sorts arr in place, also returns the array.
 * Eltsize is the number of array items per element.
 * compelt is the offset of the elt to compare within the array.
 */

reset() {
    return 0;
    }

#define Lchild(x) (x + x + eltsize)
#define Parent(x) ((x - eltsize) / 2)
#define LRchild(x) (x + eltsize)

array sort(array a, int eltsize, int compelt) {
    int N = sizeof(a);
    if (eltsize < 1)
	eltsize = 1;
    if (N % eltsize)
	throw("Sort: Array size not a multiple of element size");
    if (compelt < 0)
	throw("Sort: Comparison element offset negative");
    if (compelt >= eltsize)
	throw("Sort: Comparison element offset too large");
    int i = 0;
/*
 * Build a heap by successive upward sifts.
 */
    while ((++i) < N) {
	int j = i;
	int k = i;
	int ai = a[i];
	do {
	    j = Parent(k);
	    int aj = a[j];
	    if (ai > aj) {
		a[k] = aj;
		}
	    else {
		a[k] = ai;
		j = 0;
		ai = a[0];
		}
	    k = j;
	    }
		while (j > 0);
	    a[j] = ai;
	}
/*
 * Sort the array with successive filtering ops.
 */
    while (--N > 0) {
	int tmp = a[N]; a[N] = a[0]; a[0] = tmp;
	tmp = 0; /* N is now one element past the array again */
        int c = Lchild(tmp);
	while (c < N) {
	    if ((c < (N-1)) && (a[c+1] > a[c]))
		c++;
	    if (a[c] > a[tmp]) {
		int t2 = a[tmp]; a[tmp] = a[c]; a[c] = t2;
		tmp = c;
		c = Lchild(c);
		}
	    else
		c = N;
	}
    }

    return a;
}

show (array a) {
    int x = 0;
    while (x < sizeof(a))
	write(" " + a[x++]);
    write("\n");
}

test(int x) {
    array a = allocate(x);
    while (--x >= 0)
	a[x] = random(100);
    show(a);
    x = sizeof(a = sort(a));
    show(a);
}