dos_compilers/Mix Power C v1/SORT.C
2024-07-01 15:26:34 -07:00

105 lines
3.1 KiB
C

/* Searching and sorting */
/* Copyright (c) Mix Software 1988 */
char *bsearch(key, base, num, width, compare)
char *key; /* search key */
char *base; /* start of array */
unsigned num; /* number of elements */
unsigned width; /* size of an element */
int (*compare)(); /* function to compare two elements */
{
char *here;
int cmp;
int i, j, k;
i = 0;
j = num-1;
do {
k = (j+i)>>1;
here = base + width*k;
cmp = (*compare)(key,here);
if (cmp == 0) { /* found - now scan down for first */
while ((here > base) && ((*compare)(key,here-width) == 0))
here -= width;
return here;
}
if (cmp < 0) j = k-1; else i=k+1;
}
while (j >= i);
return NULL;
} /* bsearch */
/* ------------------------------------------------------------ */
void qsort(base, num, width, compare)
char *base; /* start of array */
unsigned num; /* number of elements */
unsigned width; /* size of an element */
int (*compare)(); /* function to compare two elements */
{
char *key;
char *first, *last, *max;
int memswap();
last = max = base+(num-1)*width;
first = base;
key = base + width*(num >> 1);
do {
while ((*compare)(first,key,width) < 0) first += width;
while ((*compare)(key,last,width) < 0) last -= width;
if (first <= last) {
if (first != last) {
memswap(first,last,width);
if (first == key) key = last;
else if (last == key) key = first;
}
first += width;
last -= width;
}
}
while (first <= last);
if (base < last) qsort(base,(last-base)/width+1,width,compare);
if (first < max) qsort(first,(max-first)/width+1,width,compare);
}
/* ------------------------------------------------------------ */
char *lsearch(key, base, num, width, compare)
char *key; /* search key */
char *base; /* start of array */
unsigned *num; /* number of elements */
unsigned width; /* size of an element */
int (*compare)(); /* function to compare two elements */
{
char *result;
result = lfind(key,base,num,width,compare);
if (result == NULL) {
result = base+(*num)*width;
memcpy(result,key,width);
(*num)++;
}
return result;
} /* lsearch */
/* ------------------------------------------------------------ */
char *lfind(key, base, num, width, compare)
char *key; /* search key */
char *base; /* start of array */
unsigned *num; /* number of elements */
unsigned width; /* size of an element */
int (*compare)(); /* function to compare two elements */
{
unsigned number = *num;
while (number != 0) {
if ((*compare)(key,base) == 0) return base;
else {
if (--number == 0) return NULL;
else base += width;
}
}
return NULL;
} /* lfind */