home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 1998 December / apc3111.iso / workshop / rsort.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  4.9 KB  |  215 lines

  1. /*****************************************************************/
  2. /* RSORT.CPP                                                     */
  3. /*                                                               */
  4. /* Radix sort code plus testbed                                  */
  5. /*                                                               */
  6. /* (c) 1998 Emmenjay Consulting Pty Ltd                          */
  7. /*                                                               */
  8. /* History                                                       */
  9. /* 05/10/98 MJS  Initial Coding                                  */
  10. /*                                                               */
  11. /*****************************************************************/
  12.  
  13.  
  14. #include <iostream.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <time.h>
  18.  
  19. // GENERIC DATA CLASS USED FOR SORTING.  MAY EASILY BE MODIFIED 
  20. // FOR PRACTICAL USE
  21. class data_t {
  22.   private:
  23.     unsigned long k;
  24.   public:
  25.     unsigned long key( void ) 
  26.       { return k; }
  27.     data_t& operator =(unsigned long newk)
  28.       { k=newk; return *this; }
  29.     unsigned bits( unsigned ndx, unsigned num )
  30.       { return (k>>ndx) & ~(~0<<num); }
  31. };
  32.  
  33. // DEFINE VARIOUS OPERATORS USED IN TESTING
  34. ostream& operator <<( ostream& os, data_t d )
  35. {
  36.   return os << d.key();
  37. }
  38.  
  39. int operator <( data_t d1, data_t d2 )
  40. {
  41.   return d1.key()<d2.key();
  42. }
  43.  
  44. int operator >( data_t d1, data_t d2 )
  45. {
  46.   return d1.key()>d2.key();
  47. }
  48.  
  49. int operator ==( data_t d1, data_t d2 )
  50. {
  51.   return d1.key()==d2.key();
  52. }
  53.  
  54.  
  55. // GENERIC ROUTINE TO SWAP TWO DATA ELEMENTS
  56. void swap( data_t& a, data_t& b )
  57. {
  58.   data_t c=a;
  59.   a = b;
  60.   b = c;
  61. }
  62.  
  63. // RADIX EXCHANGE SORT ROUTINE
  64. // a is an array of data
  65. // l is the left index into a
  66. // r is the right index into a
  67. // b is the bit on which we are currently sorting
  68. void rexch( data_t a[], int l, int r, int b )
  69. {
  70.   if (r>l && b>=0) {
  71.     int ir =r;
  72.     int il =l;
  73.     while (il<ir) {
  74.       while (!a[il].bits(b,1) && il<ir) il++;
  75.       while (a[ir].bits(b,1) && il<ir) ir--;
  76.       swap( a[il], a[ir] );
  77.     }
  78.     if (!a[r].bits(b,1)) ir++;
  79.     rexch( a, l, ir-1, b-1 );
  80.     rexch( a, ir, r, b-1 );
  81.   }
  82. }
  83.  
  84. // WRAPPER FOR RADIX EXCHANGE SORT 
  85. void resort( data_t a[], int num )
  86. {
  87.   rexch( a, 0, num-1, 31 );
  88. }
  89.  
  90.  
  91. // STRAIGHT RADIX SORT
  92. #define m 8   /* number of bits to look at at once */
  93. #define M 256 /* 2**m */
  94. #define w 32  /* bits in key */
  95.  
  96. void rssort( data_t a[], int N )
  97. {
  98.   int i, ipass;
  99.   int count[M];
  100.   data_t *b = new data_t[N];
  101.  
  102.   for (ipass = 0; ipass < w/m; ipass++) {
  103.     for (i = 0; i <  M; i++) count[i] = 0;
  104.     for (i = 0; i < N; i++) 
  105.       count[a[i].bits(ipass*m, m)]++;
  106.     for (i = 1; i <  M; i++) 
  107.       count[i] += count[i-1];
  108.     for (i = N-1; i >= 0; i--)
  109.       b[--count[a[i].bits(ipass*m, m)]] = a[i];
  110.     for (i = 0; i < N; i++) a[i] = b[i];
  111.   }
  112.   delete b;
  113. }
  114.  
  115. // SLOW BUBBLE SORT
  116. void bsort( data_t a[], int num )
  117. {
  118.   for (int i=1; i<num; i++)
  119.     for (int j=i; j>0; j--)
  120.       if (a[j-1].key() > a[j].key())
  121.         swap( a[j-1], a[j] );
  122. }
  123.  
  124. // PARTITION ROUTINE FOR QUICK SORT
  125. int partition(data_t a[], int l, int r)
  126. {
  127.   int i = l-1, j = r; data_t v = a[r];
  128.   for (;;) { 
  129.     while (a[++i] < v) ;
  130.     while (v < a[--j]) if (j == l) break;
  131.     if (i >= j) break;
  132.     swap(a[i], a[j]);
  133.   }
  134.   swap(a[i], a[r]);
  135.   return i;
  136. }
  137.  
  138. // GENERIC QUICK SORT
  139. void quicksort(data_t a[], int l, int r)
  140. {
  141.   if (r <= l) return;
  142.   int i = partition(a, l, r);
  143.   quicksort(a, l, i-1);
  144.   quicksort(a, i+1, r);
  145. }
  146.  
  147. // WRAPPER FOR QUICK SORT
  148. void qsort(data_t a[], int N)
  149. {
  150.   quicksort( a, 0, N-1 );
  151. }
  152.  
  153.  
  154. // NUMBER OF KEYS TO SORT
  155. #define MAX 250000
  156.  
  157. // DATA TO SORT
  158. static data_t a[MAX];
  159.  
  160.  
  161. int main( void )
  162. {
  163.   clock_t start, end;
  164.   int i;
  165.  
  166.   printf( "Sorting %d values\n", MAX );
  167.  
  168.   srand( 1 );
  169.   for (i=0; i<MAX; i++) {
  170.     a[i] = rand()*rand();
  171.   }
  172.   start = clock();
  173.   resort( a, MAX );
  174.   end = clock();
  175.   printf( "Radix Exchange Sort took %.3f seconds\n", 
  176.           (double)(end-start)/CLOCKS_PER_SEC );
  177.  
  178.   srand( 1 );
  179.   for (i=0; i<MAX; i++) {
  180.     a[i] = rand()*rand();
  181.   }
  182.   start = clock();
  183.   rssort( a, MAX );
  184.   end = clock();
  185.   printf( "Straight Radix Sort took %.3f seconds\n", 
  186.           (double)(end-start)/CLOCKS_PER_SEC );
  187.  
  188.   srand( 1 );
  189.   for (i=0; i<MAX; i++) {
  190.     a[i] = rand()*rand();
  191.   }
  192.   start = clock();
  193.   qsort( a, MAX );
  194.   end = clock();
  195.   printf( "Quick Sort took %.3f seconds\n", 
  196.           (double)(end-start)/CLOCKS_PER_SEC );
  197.  
  198. // OMITTED BUBBLE SORT AS IT IS TOO SLOW
  199. //  srand( 1 );
  200. //  for (i=0; i<MAX; i++) {
  201. //    a[i] = rand()*rand();
  202. //  }
  203. //  start = clock();
  204. //  bsort( a, MAX );
  205. //  end = clock();
  206. //  printf( "Bubble Sort took %.3f seconds\n", 
  207. //          (double)(end-start)/CLOCKS_PER_SEC );
  208.  
  209. //  for (i=0; i<MAX; i++)
  210. //    cout << a[i] << ' ';
  211. //  cout << '\n';
  212.  
  213.   return 0;
  214. }
  215.