Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/clib/qsort.c
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

81 lines
1.9 KiB
C

/**************************************************************************
*
* q s o r t F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "qsort" sorts the "number" of items, each of length "size", starting
* at "base", using function "compare" to compare 2 items in the vector.
*
* Calling sequence:
* ret = qsort(base,number,size,compar)
* Where:
* ret = always 0
* base -> start of items vector
* number = number of elements in vector
* size = number of bytes per item in vector
* compar -> comparator function, taking ptrs to items,
* returning WORD:
* compar(a,b) < 0 if *a < *b
* compar(a,b) == 0 if *a == *b
* compar(a,b) > 0 if *a > *b
*
* "qsort" uses the quicksort algorithm by C.A.R. Hoare.
* Ref: "Software Tools in Pascal" by Kernighan & Plauger.
*****************************************************************************/
#include <portab.h>
#define LINEPOS(nn) ((nn)*siz + bas)
#define EXCHANGE(aa,bb) _swap(aa,bb,siz)
WORD qsort(bas,num,siz,cmp)
BYTE *bas;
WORD num;
WORD siz;
WORD (*cmp)();
{
REG WORD i,j;
REG BYTE *pivline;
if( num > 1 )
{
i = 0;
j = num-1;
pivline = LINEPOS(j); /* choose last line for pvt */
do{
while( i<j && (*cmp)(LINEPOS(i),pivline) <= 0 )
i++;
while( j>i && (*cmp)(LINEPOS(j),pivline) >= 0 )
j--;
if( i<j ) /* out of order pair */
EXCHANGE(LINEPOS(i),LINEPOS(j));
}while( i<j );
EXCHANGE(LINEPOS(i),pivline);
if( i < num-1-i ) /* sort shorter subset 1st */
{
qsort( bas, i, siz, cmp);
qsort( LINEPOS(i+1), num-1-i, siz, cmp);
} else
{
qsort( LINEPOS(i+1), num-1-i, siz, cmp);
qsort( bas, i, siz, cmp);
}
}
return(0);
}
VOID _swap(a,b,wid)
REG BYTE *a;
REG BYTE *b;
REG WORD wid;
{
REG BYTE tmp;
if( a != b )
for( ; wid-- > 0; a++, b++ )
{
tmp = *a;
*a = *b;
*b = tmp;
}
}