which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			166 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* s4quick.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved.
 | 
						|
 | 
						|
   Iterative 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 is
 | 
						|
   proportional to 'n'.  For example, if there were 1000 items to
 | 
						|
   sort, the Quick Sort could, in the worst case, call itself
 | 
						|
   1000 times.
 | 
						|
 | 
						|
   This routine assumes that there is a record number after the sort
 | 
						|
   data for final comparison resolutions in case that two keys are the same.
 | 
						|
   */
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
#ifndef S4UNIX
 | 
						|
#ifdef __TURBOC__
 | 
						|
#pragma hdrstop
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
static void flip( int i, int j ) ;
 | 
						|
static int greater( int i, int j ) ;
 | 
						|
static void sort( void ) ;
 | 
						|
 | 
						|
static void **pointers ;
 | 
						|
static int n_pointers ;
 | 
						|
static int sort_len ;
 | 
						|
S4CMP_FUNCTION *cmp ;
 | 
						|
 | 
						|
static void flip( int i, int j )
 | 
						|
{
 | 
						|
  void *flip_data;
 | 
						|
  flip_data  = pointers[i] ;
 | 
						|
  pointers[i] = pointers[j] ;
 | 
						|
  pointers[j] = flip_data ;
 | 
						|
}
 | 
						|
 | 
						|
static int greater( int i, int j )
 | 
						|
{
 | 
						|
  long l1, l2 ;
 | 
						|
  int rc ;
 | 
						|
 | 
						|
  rc = (*cmp)( pointers[i], pointers[j], sort_len ) ;
 | 
						|
  if ( rc > 0 )
 | 
						|
    return 1 ;
 | 
						|
  if ( rc < 0 )
 | 
						|
    return 0 ;
 | 
						|
 | 
						|
  memcpy( (void *)&l1, ((char *)pointers[i])+sort_len, sizeof(long) ) ;
 | 
						|
  memcpy( (void *)&l2, ((char *)pointers[j])+sort_len, sizeof(long) ) ;
 | 
						|
  return l1 > l2 ;
 | 
						|
}
 | 
						|
 | 
						|
void s4quick( void **p, int p_n, S4CMP_FUNCTION *cmp_routine, int width )
 | 
						|
{
 | 
						|
  cmp = cmp_routine ;
 | 
						|
  pointers = p ;
 | 
						|
  n_pointers = p_n ;
 | 
						|
  sort_len = width ;
 | 
						|
  sort() ;
 | 
						|
}
 | 
						|
 | 
						|
static void sort()
 | 
						|
{
 | 
						|
  /* A stack size of 32 is enough to sort four billion items. */
 | 
						|
  int stack_start[32], stack_end[32], f, l, num, j, i, middle, stack_on ;
 | 
						|
 | 
						|
  stack_on = 0 ;
 | 
						|
  stack_start[0] = 0 ;
 | 
						|
  stack_end[0] = n_pointers - 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++ ;
 | 
						|
#ifdef S4DEBUG
 | 
						|
        if ( i >= n_pointers )
 | 
						|
          e4severe( e4result, E4_RESULT_INQ ) ;
 | 
						|
#endif
 | 
						|
      }
 | 
						|
 | 
						|
      j = l ;
 | 
						|
      while( greater( j, f ) )
 | 
						|
        j-- ;
 | 
						|
 | 
						|
      while ( i < j )
 | 
						|
      {
 | 
						|
        flip( i, j ) ;
 | 
						|
        i++ ;
 | 
						|
 | 
						|
        while( greater( f, i ) )
 | 
						|
        {
 | 
						|
          i++ ;
 | 
						|
#ifdef S4DEBUG
 | 
						|
          if ( i >= n_pointers )
 | 
						|
            e4severe( e4result, E4_RESULT_INQ ) ;
 | 
						|
#endif
 | 
						|
        }
 | 
						|
        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 ;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |