[3ae31e9] | 1 | /*
|
---|
| 2 | =============================================================================
|
---|
| 3 | qsort.c -- quicksort algorithm
|
---|
| 4 | Version 2 -- 1989-01-12 -- D.N. Lynx Crowe
|
---|
| 5 | =============================================================================
|
---|
| 6 | */
|
---|
| 7 |
|
---|
| 8 | #include "stddefs.h"
|
---|
| 9 |
|
---|
| 10 | static unsigned qscnt; /* size of an element */
|
---|
| 11 | static int (*qscmp)(); /* comparison function */
|
---|
| 12 |
|
---|
| 13 | /*
|
---|
| 14 | =============================================================================
|
---|
| 15 | qsexch() -- exchange two elements
|
---|
| 16 | =============================================================================
|
---|
| 17 | */
|
---|
| 18 |
|
---|
| 19 | static
|
---|
| 20 | qsexch(ip, jp)
|
---|
| 21 | register char *ip, *jp;
|
---|
| 22 | {
|
---|
| 23 | register unsigned n;
|
---|
| 24 | register char c;
|
---|
| 25 |
|
---|
| 26 | n = qscnt;
|
---|
| 27 |
|
---|
| 28 | do {
|
---|
| 29 | c = *ip;
|
---|
| 30 | *ip++ = *jp;
|
---|
| 31 | *jp++ = c;
|
---|
| 32 |
|
---|
| 33 | } while (--n);
|
---|
| 34 | }
|
---|
| 35 |
|
---|
| 36 | /* |
---|
| 37 |
|
---|
| 38 | */
|
---|
| 39 |
|
---|
| 40 | /*
|
---|
| 41 | =============================================================================
|
---|
| 42 | qstexc() - circular exchange of 3 elements
|
---|
| 43 | =============================================================================
|
---|
| 44 | */
|
---|
| 45 |
|
---|
| 46 | static
|
---|
| 47 | qstexc(ip, jp, kp)
|
---|
| 48 | register char *ip, *jp, *kp;
|
---|
| 49 | {
|
---|
| 50 | register unsigned n;
|
---|
| 51 | register char c;
|
---|
| 52 |
|
---|
| 53 | n = qscnt;
|
---|
| 54 |
|
---|
| 55 | do {
|
---|
| 56 |
|
---|
| 57 | c = *ip;
|
---|
| 58 | *ip++ = *kp;
|
---|
| 59 | *kp++ = *jp;
|
---|
| 60 | *jp++ = c;
|
---|
| 61 |
|
---|
| 62 | } while (--n);
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 | /* |
---|
| 66 |
|
---|
| 67 | */
|
---|
| 68 |
|
---|
| 69 | /*
|
---|
| 70 | =============================================================================
|
---|
| 71 | qsort1() -- Quicksort algorithm driver
|
---|
| 72 | =============================================================================
|
---|
| 73 | */
|
---|
| 74 |
|
---|
| 75 | static
|
---|
| 76 | qsort1(a, l)
|
---|
| 77 | char *a, *l;
|
---|
| 78 | {
|
---|
| 79 | register char *hp, *i, *j;
|
---|
| 80 | register unsigned es, n;
|
---|
| 81 | register int c;
|
---|
| 82 | char *lp;
|
---|
| 83 |
|
---|
| 84 | es = qscnt;
|
---|
| 85 |
|
---|
| 86 | start:
|
---|
| 87 | if ((n = (long)l - (long)a) LE es)
|
---|
| 88 | return;
|
---|
| 89 |
|
---|
| 90 | n = es * (n / (2 * es));
|
---|
| 91 | hp = lp = a + n;
|
---|
| 92 | i = a;
|
---|
| 93 | j = l - es;
|
---|
| 94 |
|
---|
| 95 | while (TRUE) {
|
---|
| 96 |
|
---|
| 97 | if (i < lp) {
|
---|
| 98 |
|
---|
| 99 | if ((c = (*qscmp)(i, lp)) EQ 0) {
|
---|
| 100 |
|
---|
| 101 | qsexch(i, lp -= es);
|
---|
| 102 | continue;
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | if (c < 0) {
|
---|
| 106 |
|
---|
| 107 | i += es;
|
---|
| 108 | continue;
|
---|
| 109 | }
|
---|
| 110 | }
|
---|
| 111 |
|
---|
| 112 | /* |
---|
| 113 |
|
---|
| 114 | */
|
---|
| 115 |
|
---|
| 116 | loop:
|
---|
| 117 | if (j > hp) {
|
---|
| 118 |
|
---|
| 119 | if ((c = (*qscmp)(hp, j)) EQ 0) {
|
---|
| 120 |
|
---|
| 121 | qsexch(hp += es, j);
|
---|
| 122 | goto loop;
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | if (c > 0) {
|
---|
| 126 |
|
---|
| 127 | if (i EQ lp) {
|
---|
| 128 |
|
---|
| 129 | qstexc(i, hp += es, j);
|
---|
| 130 | i = lp += es;
|
---|
| 131 | goto loop;
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | qsexch(i, j);
|
---|
| 135 | j -= es;
|
---|
| 136 | i += es;
|
---|
| 137 | continue;
|
---|
| 138 | }
|
---|
| 139 |
|
---|
| 140 | j -= es;
|
---|
| 141 | goto loop;
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | if (i EQ lp) {
|
---|
| 145 |
|
---|
| 146 | if (((long)lp - (long)a) GE ((long)l - (long)hp)) {
|
---|
| 147 |
|
---|
| 148 | qsort1(hp + es, l);
|
---|
| 149 | l = lp;
|
---|
| 150 |
|
---|
| 151 | } else {
|
---|
| 152 |
|
---|
| 153 | qsort1(a, lp);
|
---|
| 154 | a = hp + es;
|
---|
| 155 | }
|
---|
| 156 |
|
---|
| 157 | goto start;
|
---|
| 158 | }
|
---|
| 159 |
|
---|
| 160 | qstexc(j, lp -= es, i);
|
---|
| 161 | j = hp -= es;
|
---|
| 162 | }
|
---|
| 163 | }
|
---|
| 164 |
|
---|
| 165 | /* |
---|
| 166 |
|
---|
| 167 | */
|
---|
| 168 |
|
---|
| 169 | /*
|
---|
| 170 | =============================================================================
|
---|
| 171 | qsort(base, n, esize, comp) -- Quicksort algorithm
|
---|
| 172 |
|
---|
| 173 | base pointer to the element at the base of the table
|
---|
| 174 |
|
---|
| 175 | n number of elements in the table
|
---|
| 176 |
|
---|
| 177 | esize element size (sizeof (*base))
|
---|
| 178 |
|
---|
| 179 | comp comparison function: comp(e1, e2)
|
---|
| 180 |
|
---|
| 181 | where: e1 and e2 are pointers to the elements to compare
|
---|
| 182 |
|
---|
| 183 | comp() must return an integer which describes the result
|
---|
| 184 | of the comparison, as follows:
|
---|
| 185 |
|
---|
| 186 | < 0 e1 < e2 (eg. -1)
|
---|
| 187 | = 0 e1 = e2
|
---|
| 188 | > 0 e1 > e2 (eg. +1)
|
---|
| 189 |
|
---|
| 190 | The string function strcmp(e1, e2), for example, might be
|
---|
| 191 | suitable for use with qsort (assuming equal length strings).
|
---|
| 192 | =============================================================================
|
---|
| 193 | */
|
---|
| 194 |
|
---|
| 195 | qsort(base, n, esize, fc)
|
---|
| 196 | char *base;
|
---|
| 197 | unsigned n;
|
---|
| 198 | unsigned esize;
|
---|
| 199 | int (*fc)();
|
---|
| 200 | {
|
---|
| 201 | qscmp = fc;
|
---|
| 202 | qscnt = esize;
|
---|
| 203 | qsort1(base, base + ((long)n * (long)esize));
|
---|
| 204 | }
|
---|