home *** CD-ROM | disk | FTP | other *** search
-
- /* (c)Copyright Sequiter Software Inc., 1987-1990. All rights reserved.
-
- u4sort_q.c
-
- Itteritive Quick Sort Algorithm
-
- This algorithm is superior to the more traditional recursive
- Quick Sort as the worst case stack size is proportional to 'log(n)'.
- In this algorithm the stack is explicitly maintained.
-
- In the recursive algorithm, the worst case depth of recursion
- proportional to 'n'. For example, if there were 1000 items to
- sort, the Quick Sort could, in the worst case, call itself
- 1000 times.
- */
-
- #include "d4all.h"
- #include "p4misc.h"
- #include <string.h>
-
- char H_PTR H_PTR ptr_ptr ;
- static int compare_width ;
- static char H_PTR flip_data ;
-
-
- static void flip( long,long ) ;
-
- static void flip( long i, long j )
- {
- flip_data = ptr_ptr[i] ;
- ptr_ptr[i] = ptr_ptr[j] ;
- ptr_ptr[j] = flip_data ;
- }
-
- static int v4greater_rc = 1 ;
- static int v4less_rc = 0 ;
- /*
- static int v4bcd_cmp = 0 ; */
-
-
- static int greater( long,long ) ;
-
- static int greater( long i, long j )
- {
- int rc ;
-
- #ifdef OS2
- rc = u4huge_cmp( ptr_ptr[i], ptr_ptr[j], compare_width ) ;
- #else
- #ifdef LANGUAGE
- rc = u4memcmp( (unsigned char *) ptr_ptr[i], (unsigned char *) ptr_ptr[j], (size_t) compare_width ) ;
- #else
- rc = memcmp( (void *) ptr_ptr[i], (void *) ptr_ptr[j], (size_t) compare_width ) ;
- #endif
- #endif
- if ( rc > 0 ) return v4greater_rc ;
-
- if ( rc == 0 )
- if ( ptr_ptr[i] > ptr_ptr[j] ) return v4greater_rc ;
-
- return v4less_rc ;
- }
-
-
- void u4sort_quick( char H_PTR H_PTR pointer_ptr, long n, int width )
- {
- /* A stack size of 32 is enough to sort four billion items. */
- long stack_start[32], stack_end[32], f, l, num, j, i, middle ;
- int stack_on ;
-
- u4huge_set( pointer_ptr[n], (int) 0xFF, (long) width ) ;
-
- ptr_ptr = pointer_ptr ;
- compare_width = width ;
-
- stack_on = 0 ;
- stack_start[0] = 0 ;
- stack_end[0] = n - 1 ;
-
- while( stack_on >= 0 )
- {
- f = stack_start[stack_on] ;
- l = stack_end[stack_on] ;
- stack_on-- ;
-
- /* Sort items 'f' to 'l' */
- while ( f < l )
- {
- /* Pick the middle item based on a sample of 3 items. */
- num = l - f ;
- if ( num < 2 )
- {
- if ( num == 1 )
- {
- /* Two Items */
- if ( greater(f,l) )
- flip(f,l) ;
- }
- break ;
- }
-
- /* Choose 'ptr_ptr[f]' to be a median of three values */
- middle = (l+f) / 2 ;
-
- if ( greater(middle,l) )
- flip(middle,l) ;
-
- if ( greater(middle,f) )
- flip(f,middle) ;
- else
- if ( greater(f,l) )
- flip(f,l) ;
-
- if ( num == 2 ) /* Special Optimization on Three Items */
- {
- flip(f,middle) ;
- break ;
- }
-
- i = f + 1 ;
- while( greater(f,i) ) i++ ;
-
- j = l ;
- while( greater(j,f) ) j-- ;
-
- while ( i<j )
- {
- flip( i,j ) ;
- i++ ;
-
- while( greater(f,i) ) i++ ;
- j-- ;
-
- while( greater(j,f) ) j-- ;
- }
-
- flip( f,j ) ;
-
- /* Both Sides are non-trivial */
- if ( j-f > l-j )
- {
- /* Left sort is larger, put it on the stack */
- stack_start[++stack_on] = f ;
- stack_end[stack_on] = j-1 ;
-
- f = j+ 1 ;
- }
- else
- {
- /* Right sort is larger, put it on the stack */
- stack_start[++stack_on] = j+1 ;
- stack_end[stack_on] = l ;
-
- l = j- 1 ;
- }
- }
- }
- }
-