#define DEBUG
/* qsort - general purpose quicksort
Author...
Copyright (c) 1984 Allen I. Holub
All rights reserved.
This program may be copied for personal, non-profit use only.
Published in Dr. Dobb's Journal #102 (Apr 85).
Usage...
Including a #define for DEBUG will make this file a stand-alone
program which sorts argv and prints the result, along with all
intermediate stages. This is pretty instructive if you want to
see how the quick sort works.
*/
#ifdef DEBUG
static int Lev=0; /* recursion level */
static int Maxlev=0; /* maximum recursion level */
int Comparisons=0, Exchanges=0;
#endif
typedef int (*PFI)(); /* pointer to a function returning int */
static PFI Comp; /* pointer to comparison routine */
static int Width; /* width of an object in bytes */
/*---------------------------------------------------------------------------*/
int argvcmp(s1p,s2p) char **s1p,**s2p;
{
/* Comparison routine for sorting an argv like list of pointers
to strings. Just remove one level of indirection and call
strcmp to do the comparison */
qsort(base,nel,width,compare)
char *base;
int nel,width;
int (*compare)();
{
/* Perform a quick sort on an array starting at base. The
array is nel elements large and width is the size of a single
element in bytes. Compare is a pointer to a comparison routine
which will be passed pointers to two elements of the array. It
should return a negative number if the left-most argument is
less than the rightmost, 0 if the two arguments are equal, a
positive number if the left argument is greater than the right.
(That is, it acts like a "subtract" operator.) If compare is 0
then the default comparison routine, argvcmp (which sorts an
argv-like array of pointers to strings), is used.
*/
#ifdef DEBUG
printf("Sorting %d element array of %d byte elements at 0x%x\n",
nel,width,base);
printf("Comparison routine at 0x%x. Unsorted list:\n",compare);
ptext(nel,base);
#endif
Width=width;
Comp=(compare==(PFI)0) ? &argvcmp : compare ;
if(nel>1)
rqsort(base,base+((nel-1)*width));
#ifdef DEBUG
printf("\nSort complete, list is:\n");
ptext(nel,base);
printf("Maximum recursion level = %d\n",Maxlev);
printf("%d comparisons and %d exchanges were performed \n",
Comparisons, Exchanges);
#endif
}
/*---------------------------------------------------------------------------*/
static rqsort(low,high)
register char *low,*high;
{
/* Workhorse function called by the access routine, qsort().
Not externally accessible. */
char *pivot,*base;
static char *a,*b; /* Used for exchanges, will not need to retain */
static int tmp,i; /* their values during the recursion so they */
/* can be static */
#ifdef DEBUG
printf("New pass, recursion level %d\n",Lev);
if (Lev>Maxlev) Maxlev=Lev;
#endif
base=low; /* remember base address of array */
pivot=high; /* partition off the pivot */
high -= Width;