home *** CD-ROM | disk | FTP | other *** search
- /* u4sort.c (c)Copyright Sequiter Software Inc., 1987, 1988, 1989. All rights reserved.
-
- Unfortunately, the 'qsort' routine in the Microsoft Library
- can give very poor worst case performance. This routine
- can be used as a replacement.
- */
-
- #include "d4base.h"
-
- #include <string.h>
-
- static size_t w ;
- static int (*c)() ;
- static char *small, *large ;
- static char flip_buffer[MAX_KEY_SIZE+4] ;
-
- static void flip(char*, char *) ;
- static void quick_sort( char *, size_t ) ;
-
- static void flip( a,b )
- char *a ;
- char *b ;
- {
- memcpy( flip_buffer, a, w ) ;
- memcpy( a, b, w ) ;
- memcpy( b, flip_buffer, w ) ;
- }
-
-
- static void quick_sort( base, num )
- char *base ;
- size_t num ;
- {
- size_t num_smaller ;
-
- if ( num < 3 )
- {
- if ( num == 2 )
- if ( (*c)( base, base+w ) > 0 )
- flip( base, base+w ) ;
- return ;
- }
-
- large = base+ w*(num-1) ;
- small = base+ w*(num>>1) ;
-
- /* base should point to a middle value fewest recursions */
- if ( (*c)( small, large ) > 0 ) flip( small, large ) ;
- if ( (*c)( small, base ) > 0 )
- flip( small, base ) ;
- else
- if ( (*c)( base, large ) > 0 )
- flip( base, large ) ;
-
- if ( num == 3 )
- {
- flip( base, small ) ;
- return ;
- }
-
- small = base + w ;
-
- while ( small < large )
- {
- if ( (*c)( small, base ) < 0 )
- {
- small += w ;
- continue ;
- }
-
- do
- {
- if ( (*c)(base, large) > 0 )
- {
- flip( small, large ) ;
- large -= w ;
- small += w ;
- break ;
- }
- large -= w ;
- } while( small < large ) ;
- }
-
- if ( (*c)(small,base) < 0 ) flip(small,base) ;
- num_smaller = (size_t) ((small-base) / w) ;
-
- quick_sort( small, num-num_smaller ) ;
- quick_sort( base, num_smaller ) ;
-
- return ;
- }
-
-
- void u4sort( base, num, width, compare )
- void *base ;
- size_t num ;
- size_t width ;
- int (*compare)() ;
- {
- w = width ;
- c = compare ;
- quick_sort( (char *) base, num ) ;
- }
-