How to write a sorting program that will sort everything?

Blair P. Houghton bhoughto at pima.intel.com
Sat Mar 23 14:34:10 AEST 1991


In article <1991Mar22.005700.17663 at minyos.xx.rmit.oz.au> rcoahk at chudich.co.rmit.oz (Alvaro Hui Kau) writes:
>Hi,
>	Recently I came into the problem of writing
>	a sorting program that needs to handle any
>	type of input.

It can't be done.  You can always define a type of input
for which "sorting" isn't defined.  For example, strings in
unix are usually sorted according to ASCII collating
sequence, so that A-Z appear before a-z; this is because,
represented as integers in the machine, this is the actual
order in which they appear.  The sort(1) program needs a
flag (usually `-f') to tell it when to sort according to
linguistic rules rather than arbitrary computer rules.

What you seem to want, however, is a program to sort any
of the basic types available in C.  This is easy.  Define
a union in which there is a tag for every one of the type
specifiers you might use:

	union c_basic_types {
	    float f;
	    double d;
	    int i;
	    ...
	};

and a set of constants you can use to flag the function:

#define SORT_FLOAT	1
#define SORT_DOUBLE	2
#define SORT_INT	3
...

and implement a switch to use the proper union tag when
the flag is passed

union c_basic_types
max( union c_basic_types x, union c_basic_types y, int sort_type )
{
    switch ( sort_type ) {
	case SORT_FLOAT:
	    return ( x.f > y.f ) ? x : y ;
	    break;
	case SORT_DOUBLE:
	    return ( x.d > y.d ) ? x : y ;
	    break;
	case SORT_INT:
	    return ( x.i > y.i ) ? x : y ;
	    break;
	...
	default:
	    /* some sort of error message for a type that isn't recognized */
	    exit(-1);
	    break;
    }
}

This is just the max() function; with an array or list of
unions you can implement a full sort.  Look into the
library function qsort(3). You can use this max function in
qsort if you modify it to use a global variable to pass the
sort_type and you have it return 1 when the value in x is
larger and 0 when the value in y is larger

main.c:
    extern int max( union c_basic_types x, c_basic_types y ); /* prototype */
    int sort_type;

    main()
    {
	union c_basic_types a[SIZE];
	extern int sort_type;

	.../* code to fill the array */...

	.../* code to set sort_type to some type */...

	qsort( a, SIZE, sizeof(a[0]), max );

	.../* code to use the sorted array */...
    }

max.c:
    int max( union c_basic_types x, c_basic_types y )
    {
	extern int sort_type;

	switch ( sort_type ) {
	    case SORT_FLOAT:
		return ( x.f > y.f );
		break;
	    case SORT_DOUBLE:
		return ( x.d > y.d );
		break;
	    case SORT_INT:
		return ( x.i > y.i );
		break;
	    ...
	    default:
		/* unrecognized type; print error message and die */
		fputs("Mickle foo and yer mama, too!",stderr);
		exit(-1);
		break;
	}
    }

The basic point here is you can't sort a type for which
you haven't defined the ordering method.  This is the
reason qsort(3) requires such a strange setup to do
its job.

The best I can do is answer your question and tell you _how_
to write it.

				--Blair
				  "It's sorting those damnable
				   '...' types that'll get
				   you every time..."



More information about the Comp.lang.c mailing list