1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/*
* MLSORT.C - sorting routines for PML
*
* Source Version: 2.0
* Software Release #92-0043
*
*/
#include "cpyright.h"
#include "pml.h"
static int
SC_DECLARE(_PM_comp, (double x1, double x2));
static void
SC_DECLARE(_PM_q_sort, (REAL *v, int *ind, int left, int right)),
SC_DECLARE(_PM_exch, (REAL *x1, REAL *y1, REAL *x2, REAL *y2));
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* PM_VAL_SORT - sort arrays containing points by x value */
void PM_val_sort(n, xp, yp)
int n;
REAL *xp, *yp;
{int gap, i, j;
for (gap = n/2; gap > 0; gap /= 2)
for (i = gap; i < n; i++)
for (j = i-gap; j >= 0; j -= gap)
{if (_PM_comp(xp[j], xp[j+gap]) <= 0)
break;
_PM_exch(xp+j, yp+j, xp+j+gap, yp+j+gap);};
return;}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* _PM_COMP - compare the values and return their relative order */
static int _PM_comp(x1, x2)
double x1, x2;
{if (x1 < x2)
return(-1);
else if (x1 > x2)
return(1);
else
return(0);}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* _PM_EXCH - exchange two (x, y) pairs */
static void _PM_exch(x1, y1, x2, y2)
REAL *x1, *y1, *x2, *y2;
{REAL tempx, tempy;
tempx = *x1;
tempy = *y1;
*x1 = *x2;
*y1 = *y2;
*x2 = tempx;
*y2 = tempy;
return;}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* PM_T_SORT - topological sort routine as described in Knuth,
* - "The Art of Computer Programming", Vol. 1, p 260-263
* - input is an array of indexes which is 2*n_dep long
* - containing n_dep pairs specifying the topology in terms
* - of relations, j < k, i.e. "j precedes k"
* - also n_dep the number of pairs and n_pts the number of
* - points to be ordered
* - the routine returns a pointer to a newly allocated list
* - of ordered indices if successful
* - NULL is returned on failure (loops present)
*/
int *PM_t_sort(in, n_dep, n_pts, ord)
int *in, n_dep, n_pts, *ord;
{int i, n, *pin, *out, *pout, *q;
int r, f, ind, dep;
sort_link *link, *nln;
link = FMAKE_N(sort_link, n_dep+n_pts+1, "PM_T_SORT:link");
q = FMAKE_N(int, n_pts+1, "PM_T_SORT:q");
/* map the partial ordering into a structured list to do the sort */
nln = link + n_pts + 1;
pin = in;
for (i = 0; i < n_dep; i++)
{ind = *pin++;
dep = *pin++;
nln->count = dep;
nln->next = link[ind].next;
link[dep].count++;
link[ind].next = nln++;};
/* initialize the output queue */
r = 0;
for (i = 1; i <= n_pts; i++)
if (link[i].count == 0)
{q[r] = i;
r = i;};
/* determine what to do about output */
if (ord == NULL)
out = pout = FMAKE_N(int, n_pts, "PM_T_SORT:out");
else
out = pout = ord;
/* do the sort */
n = n_pts;
f = q[0];
while (f != 0)
{*pout++ = f;
n--;
/* remove relations of the form "f < k" for some k of the system */
for (nln = link[f].next; nln != NULL; nln = nln->next)
if (--link[nln->count].count == 0)
{q[r] = nln->count;
r = nln->count;};
f = q[f];};
SFREE_N(link, n_dep+n_pts+1);
SFREE_N(q, n_pts+1);
/* if n is non-zero there was a loop in the topology */
if (n != 0)
{SFREE(out);
out = NULL;};
return(out);}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* PM_Q_SORT - Sort an array of indexes on z;
* - input is z, an array of REALS,
* ind, array of indexes
* n, number of entries.
* - output is array z sorted and
* array ind sorted.
*/
void PM_q_sort(z, ind, n)
REAL *z;
int *ind, n;
{_PM_q_sort(z, ind, 0, n-1);
return;}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* _PM_SWAP - Swap elements i and j in arrays v and ind.
*/
void _PM_swap(v, ind, i, j)
REAL *v;
int *ind, i, j;
{REAL temp;
int itemp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
itemp = ind[i];
ind[i] = ind[j];
ind[j] = itemp;
return;}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* _PM_Q_SORT - quicksort, taken from "The C Programming Language",
* - 2nd Edition, by Kernighan and Ritchie, pp 87-88.
*/
static void _PM_q_sort(v, ind, left, right)
REAL *v;
int *ind, left, right;
{int i, last;
if (left >= right)
return;
_PM_swap(v, ind, left, (left+right)/2);
last = left;
for (i = left+1; i <= right; i++)
if (v[i] < v[left])
_PM_swap(v, ind, ++last, i);
_PM_swap(v, ind, left, last);
_PM_q_sort(v, ind, left, last-1);
_PM_q_sort(v, ind, last+1, right);
return;}
|