home *** CD-ROM | disk | FTP | other *** search
/ ActiveX Programming Unleashed CD / AXU.iso / jgl_1_1 / jgl_1_1.exe / src / Sorting.java < prev    next >
Encoding:
Java Source  |  1996-09-10  |  5.7 KB  |  197 lines

  1. // Copyright(c) 1996 ObjectSpace, Inc.
  2. // Portions Copyright(c) 1995, 1996 Hewlett-Packard Company.
  3.  
  4. package jgl;
  5.  
  6. /**
  7.  * The Sorting class contains generic sorting algorithms.
  8.  * <p>
  9.  * @see jgl.examples.SortingExamples
  10.  * @version 1.1
  11.  * @author ObjectSpace, Inc.
  12.  */
  13.  
  14. public final class Sorting
  15.   {
  16.   static final int stlThreshold = 16;
  17.   Sequence base;
  18.   BinaryPredicate comparator;
  19.  
  20.   private Sorting()
  21.     {
  22.     }
  23.  
  24.   /**
  25.    * Sort the elements in a sequence according to their hash code. The object with the
  26.    * smallest hash code is placed first. The time complexity is O(NlogN) and the space 
  27.    * complexity is constant.
  28.    * @param first An iterator positioned at the first element of the sequence.
  29.    * @param last An iterator positioned immediately after the last element of the sequence.
  30.    * @exception java.lang.IllegalArgumentException is thrown if the iterators do not have
  31.    * Sequence containers -or- if there containers are different.
  32.    */
  33.   public static void sort( ForwardIterator first, ForwardIterator last )
  34.     {
  35.     sort( first, last, new HashComparator() );
  36.     }
  37.  
  38.   /**
  39.    * Sort the elements in a sequence using a comparator. The time complexity is O(NlogN)
  40.    * and the space complexity is constant.
  41.    * @param first An iterator positioned at the first element of the sequence.
  42.    * @param last An iterator positioned immediately after the last element of the sequence.
  43.    * @param comparator A binary function that returns true if its first operand should be positioned before its second operand.
  44.    * @exception java.lang.IllegalArgumentException is thrown if the iterators do not have
  45.    * Sequence containers.
  46.    */
  47.   public static void sort( ForwardIterator first, ForwardIterator last, BinaryPredicate comparator )
  48.     {
  49.     new Sorting( first, last, comparator );
  50.     }
  51.  
  52.   /**
  53.    * Sort the elements in a Sequence container according to their hash code. The 
  54.    * object with the smallest hash code is placed first. The time complexity is O(NlogN) 
  55.    * and the space complexity is constant.
  56.    * @param container A Sequence container.
  57.    */
  58.   public static void sort( Sequence container )
  59.     {
  60.     sort( container.start(), container.finish(), new HashComparator() );
  61.     }
  62.  
  63.   /**
  64.    * Sort the elements in a random access container using a comparator. The time 
  65.    * complexity is O(NlogN) and the space complexity is constant.
  66.    * @param container A random access container.
  67.    * @param comparator A BinaryFunction that returns true if its first operand should be positioned before its second operand.
  68.    */
  69.   public static void sort( Sequence container, BinaryPredicate comparator )
  70.     {
  71.     sort( container.start(), container.finish(), comparator );
  72.     }
  73.  
  74.   private Sorting( ForwardIterator first, ForwardIterator last, BinaryPredicate comparit )
  75.     {
  76.     if ( ( !(first.getContainer() instanceof Sequence) ) ||
  77.          ( !(last.getContainer() instanceof Sequence) ) )
  78.       throw new IllegalArgumentException( "iterator containers must be a Sequence" );
  79.  
  80.     base = (Sequence) first.getContainer();
  81.     comparator = comparit;
  82.    
  83.     // calculate first and last index into the sequence.
  84.     int start = (base.start()).distance( first );
  85.     int finish = (base.start()).distance( last );
  86.   
  87.     quickSortLoop( start, finish );
  88.     finalInsertionSort( start, finish );
  89.     }
  90.  
  91.   void finalInsertionSort( int first, int last )
  92.     {
  93.     if( last - first > stlThreshold )
  94.       {
  95.       int limit = first + stlThreshold;
  96.  
  97.       for( int i = first + 1; i < limit; i++ )
  98.         linearInsert( first, i );
  99.  
  100.       for( int i = limit; i < last; i++ )
  101.         unguardedLinearInsert( i, base.at( i ) );
  102.       }
  103.     else
  104.       {
  105.       for( int i = first + 1; i < last; i++ )
  106.         linearInsert( first, i );
  107.       }
  108.     }
  109.  
  110.   void unguardedLinearInsert( int last, Object value )
  111.     {
  112.     int next = last - 1;
  113.  
  114.     while( comparator.execute( value, base.at( next ) ) )
  115.       base.put( last--, base.at( next-- ) );
  116.  
  117.     base.put( last, value );
  118.     }
  119.  
  120.   void linearInsert( int first, int last )
  121.     {
  122.     Object value = base.at( last );
  123.  
  124.     if( comparator.execute( value, base.at( first ) ) )
  125.       {
  126.       for( int i = last; i > first; i-- )
  127.         base.put( i, base.at( i - 1 ) );
  128.  
  129.       base.put( first, value );
  130.       }
  131.     else
  132.       {
  133.       unguardedLinearInsert( last, value );
  134.       }
  135.     }
  136.  
  137.   void quickSortLoop( int first, int last )
  138.     {
  139.     while( last - first > stlThreshold )
  140.       {
  141.       Object pivot;
  142.       Object a = base.at( first );
  143.       Object b = base.at( first + (last - first ) / 2 );
  144.       Object c = base.at( last - 1 );
  145.  
  146.       if( comparator.execute( a, b ) )
  147.         {
  148.         if( comparator.execute( b, c ) )
  149.           pivot = b;
  150.         else if( comparator.execute( a, c ) )
  151.           pivot = c;
  152.         else  
  153.           pivot = a;
  154.         }
  155.       else if( comparator.execute( a, c ) )
  156.         pivot = a;
  157.       else if( comparator.execute( b, c ) )
  158.         pivot = c;
  159.       else
  160.         pivot = b;
  161.  
  162.       int cut = first;
  163.       int lastx = last;
  164.  
  165.       while( true )
  166.         {
  167.         while( comparator.execute( base.at( cut ), pivot ) )
  168.           ++cut;
  169.  
  170.         --lastx;
  171.  
  172.         while( comparator.execute( pivot, base.at( lastx ) ) )
  173.           --lastx;
  174.  
  175.         if( cut >= lastx )
  176.           break;
  177.  
  178.         Object tmp = base.at( cut );
  179.         base.put( cut++, base.at( lastx ) );
  180.         base.put( lastx, tmp );
  181.         }
  182.  
  183.       if( cut - first >= last - cut )
  184.         {
  185.         quickSortLoop( cut, last );
  186.         last = cut;
  187.         }
  188.       else
  189.         {
  190.         quickSortLoop( first, cut );
  191.         first = cut;
  192.         }
  193.       }
  194.     }
  195.   }
  196.  
  197.