home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 19.ddi / SAMPLES / PROFILER / DOS / QSORT.C_ / QSORT.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  6.9 KB  |  226 lines

  1.  /*
  2.  * QSORT.C   C version of the quicksort algorithm
  3.  *
  4.  * This program is described in Chapters 2 and 3 of the Microsoft Source
  5.  * Profiler User's Guide.
  6.  *
  7.  */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. /* Macro to get a random integer within a specified range */
  13. #define getrandom( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))
  14.  
  15. /* Maximum number of words to sort */
  16. #define MAXNUMWORDS 1500
  17. /* Maximum word length (in characters) */
  18. #define MAXWORDSIZE 15
  19.  
  20.  
  21. char WordArray[MAXNUMWORDS][MAXWORDSIZE];
  22. int  WordIndex[MAXNUMWORDS];
  23.  
  24. void usage(void);
  25. int  GetWords(char *filename);
  26. void QuickSort(int Low, int High );
  27. void SwapWords( int index1, int index2 );
  28. void OutWords(int NumWords, char *filename);
  29.  
  30. /* main - The main function calls functions that load the input file,
  31.  * sort it, and save the output to another file. It also calls the usage
  32.  * statement on bad command-line arguments and sets up the index array.
  33.  */
  34. int main (int argc, char *argv[])
  35. {
  36.     int NumWords;
  37.     int index;
  38.     puts( "QSORT.C" );
  39.     if ( argc != 3 )
  40.         usage();
  41.     printf( "Loading %s\n", argv[1] );
  42.     NumWords = GetWords( argv[1] );
  43.     /* Initialize WordIndex array */
  44.     for ( index = 0; index < NumWords; index++ )
  45.         WordIndex[index] = index;
  46.     printf( "Loaded %i words.\n", NumWords );
  47.     puts( "Sorting" );
  48.     if ( NumWords > 0 )
  49.     {
  50.         QuickSort( 0, NumWords-1 );
  51.         OutWords( NumWords, argv[2] );
  52.     }
  53.  
  54.     return 0;
  55. }
  56.  
  57. /* GetWords - GetWords loads and parses an ASCII text file and stores each
  58.  * word into WordArray. Returns the number of words read.
  59.  */
  60. int GetWords(char *filename)
  61. {
  62.     FILE    *FileHandle;
  63.     int     WordNumber = 0;
  64.     int     CharNumber = 0;
  65.     char    TempChar   = '\0';
  66.  
  67.     FileHandle = fopen(filename, "r");
  68.     if (FileHandle == NULL)
  69.         {
  70.         puts("Error opening input file.");
  71.         return 0;
  72.         }
  73.  
  74.     while ((WordNumber < MAXNUMWORDS) && (TempChar != EOF))
  75.     {
  76.         TempChar = fgetc(FileHandle);
  77.         switch(TempChar)
  78.         {
  79.             /* Word delimiters */
  80.             case ' ' :
  81.             case '\n':
  82.             case '\t':
  83.                 /* Start new word unless at beginning */
  84.                 if (CharNumber != 0)
  85.                 {
  86.                     WordArray[WordNumber][CharNumber] = '\0';
  87.                     CharNumber = 0;
  88.                     WordNumber++;
  89.                 }
  90.                 break;
  91.             /* Quit if at end of file */
  92.             case EOF:
  93.                 break;
  94.             /* Characters to add to word */
  95.             default:
  96.                 WordArray[WordNumber][CharNumber] = TempChar;
  97.                 /* Truncate word if too long */
  98.                 if (++CharNumber >= MAXWORDSIZE)
  99.                 {
  100.                     WordArray[WordNumber][CharNumber-1] = '\0';
  101.                     CharNumber = 0;
  102.                     WordNumber++;
  103.                     /* Skip over remaining characters */
  104.                     while ((TempChar != ' ') && (TempChar != '\n') &&
  105.                            (TempChar != '\t'))
  106.                          TempChar = fgetc(FileHandle);
  107.                 }
  108.                 break;
  109.         }
  110.     }
  111.     fclose( FileHandle );
  112.     return  WordNumber;
  113. }
  114.  
  115. /* QuickSort - QuickSort works by picking a random "pivot" element,
  116.  * then moving every element that is bigger to one side of the pivot,
  117.  * and every element that is smaller to the other side. QuickSort is
  118.  * then called recursively with the two subdivisions created by the pivot.
  119.  * Once the number of elements in a subdivision reaches two, the recursive
  120.  * calls end and the array is sorted.
  121.  */
  122. void QuickSort( int Low, int High )
  123. {
  124.     int Up, Down;
  125.  
  126.     char cBreak[MAXWORDSIZE];
  127.  
  128.     if( Low < High )
  129.     {
  130.         /* Only two elements in this subdivision; swap them if they are
  131.          * out of order, then end recursive calls.
  132.          */
  133.         if( (High - Low) == 1 )
  134.         {
  135.             if( stricmp( WordArray[WordIndex[Low]], WordArray[WordIndex[High]] ) > 0 )
  136.                 SwapWords( Low, High );
  137.         }
  138.         else
  139.         {
  140.             /* Pick a pivot element at random, then move it to the end. */
  141.             SwapWords( High, getrandom( Low, High ) );
  142.             strcpy( cBreak, WordArray[WordIndex[High]] );
  143.             do
  144.             {
  145.                 /* Move in from both sides towards the pivot element. */
  146.                 Up = Low;
  147.                 Down = High;
  148.                 while( (Up < Down) &&
  149.                        (stricmp( WordArray[WordIndex[Up]], cBreak ) <= 0) )
  150.                         Up++;
  151.                 while( (Down > Up) &&
  152.                        (stricmp( WordArray[WordIndex[Down]], cBreak ) >= 0) )
  153.                         Down--;
  154.                 /* If we haven't reached the pivot, it means that two
  155.                  * elements on either side are out of order, so swap them.
  156.                  */
  157.                 if( Up < Down )
  158.                     SwapWords( Up, Down );
  159.             } while ( Up < Down );
  160.  
  161.             /* Move pivot element back to its proper place in the array. */
  162.             SwapWords( Up, High );
  163.  
  164.             /* Recursively call the QuickSort procedure (pass the smaller
  165.              * subdivision first to use less stack space).
  166.              */
  167.             if( (Up - Low) < (High - Up) )
  168.             {
  169.                 QuickSort( Low, Up - 1 );
  170.                 QuickSort( Up + 1, High );
  171.             }
  172.             else
  173.             {
  174.                 QuickSort( Up + 1, High );
  175.                 QuickSort( Low, Up - 1 );
  176.             }
  177.         }
  178.     }
  179. }
  180.  
  181. /* SwapWords - SwapWords swaps the WordIndex index values of two words,
  182.  * thereby swapping the indexed positions of the words.
  183.  */
  184. void SwapWords( int index1, int index2 )
  185. {
  186.     int     TempIndex;
  187.     TempIndex = WordIndex[index1];
  188.     WordIndex[index1] = WordIndex[index2];
  189.     WordIndex[index2] = TempIndex;
  190. }
  191.  
  192. /* OutWords - OutWords writes the sorted array of words to a file.
  193.  */
  194. void OutWords(int NumWords, char *filename)
  195. {
  196.     FILE *FileHandle;
  197.     int TempIndex;
  198.     FileHandle = fopen(filename, "w");
  199.     if (FileHandle == NULL)
  200.         {
  201.         puts("Error opening output file.");
  202.         return;
  203.         }
  204.     for (TempIndex=0; TempIndex < NumWords; TempIndex++ )
  205.         if ( fputs( WordArray[WordIndex[TempIndex]], FileHandle ) == EOF)
  206.         {
  207.             puts("Error writing output file.");
  208.             break;
  209.         }
  210.         else
  211.             fputs( "\n", FileHandle );
  212.     fclose( FileHandle );
  213. }
  214.  
  215. /* usage - The usage function displays the syntax of QSORT and exits to the
  216.  * system.
  217.  */
  218. void    usage(void)
  219. {
  220.     puts("Performs QuickSort on a file and sends results to a file.");
  221.     puts("Usage: QSORT <input> <output>");
  222.     puts("Where <input> is the name of the text file to sort and <output> is the");
  223.     puts("name of the file to store the sorted output.");
  224.     exit (0);
  225. }
  226.