Function to Partition an Array a la Quicksort

Test Driver and Swap Function Included

If you wish you can just copy the swap and partition functions from this file and put them into whatever program you want. If you want to run the test, then just copy the whole file, compile, and run like this:

a.out < numbers

where numbers is the little file of test data in this directory.


-------------------------------------------------------------------------------------------
|s|s|s|s|s|s|s|s|s|s|s|s|s|s|s|s|e|e|e|l|l|l|l|l|l|l|l|u|u|u|u|u|u|u|u|u|u|u|u|u|u|u|u|u|u|
-------------------------------------------------------------------------------------------
 ^                             ^       ^firstLarger    ^firstUnknown                     ^ right
left                       lastSmaller
If the element at the firstUnknown position is greater than the pivot, then the algorithm simply increments firstUnknown

If the element at the firstUnknown position is equal to the pivot, then the algorithm swaps the element at position firstUnknown with the element at position firstLarger. Afterwards the algorithm increments both firstLarger and firstUnknown.

If the element at the firstUnknown position is less than the pivot then two swaps are performed: the first swap is as above - 'firstUnknown' is swapped with 'firstLarger'. In the second swap 'firstLarger' is swapped with 'lastSmaller+1'. Afterwards the algorithm increments lastSmaller, firstLarger, and firstUnknown.

#include <iostream.h>


/* ================================================== */
/*                          SWAP                      */
/* ================================================== */
void swap (int & i , int & j)
{
  int temp = i ;
  i = j ;
  j = temp ;
}

/* ================================================== */
/*                       PARTITION                    */
/* ================================================== */
/*

     This function partitions array A between indices left and
     right.

     Elements less than pivot are placed in slots numbered left
     through lastSmaller.  If no elements are less than pivot
     then the value returned for lastSmaller is left-1.

     Elements greater than pivot are placed in the slots
     numbered firstLarger through right.  If no elements are
     greater than pivot then the value returned for firstLarger
     is right+1.

     Elements equal to the pivot are in slots numbered
     lastSmaller+1 through firstLarger-1.  If no elements are
     equal to the pivot then lastSmaller+1 = firstLarger >
     firstLarger-1.

*/
void partition (  int A[], int left, int right, int pivot, 
                    int & lastSmaller, int & firstLarger )
{

/* Initialize */

     lastSmaller = left-1;  firstLarger = left; 
     int firstUnknown = left ;
/*

   INVARIANT: All elements from left through lastSmaller are
   smaller than the pivot.  All elements from lastSmaller+1
   through firstLarger-1 are equal to the pivot.  All elements
   from firstLarger to firstUnknown-1 are larger than the
   pivot.  Initially this invariant is true trivially, because
   all the indicated sets are empty.
   
*/
     int unknown ;
     while (firstUnknown <= right )
     {
       unknown = A[firstUnknown] ;
       if ( unknown <= pivot)
       {  
         swap(A[firstLarger], A[firstUnknown]) ;
         if ( unknown < pivot)
         {
           swap(A[lastSmaller+1], A[firstLarger]) ;
           lastSmaller++ ;
         }
         firstLarger++ ;
       }
       firstUnknown++ ;
     }
}


int main ()
{
  int i, j, A[25], B[25] , lastSmaller, firstLarger ;

  for (i=0; i<25; i++) cin >> A[i] ;
  for (i=0; i<25; i++)
  {
    for (j=0; j<25; j++) B[j]=A[j] ;
    partition (B, 0, 24, i, lastSmaller, firstLarger) ;
    cout << "pivot is: " << i << "   " ;
    cout << "lastSmaller is: " << lastSmaller << "   " ;
    cout << "firstLarger is: " << firstLarger << endl ;
    for (j=0; j<25; j++) cout << B[j] << " " ;
    cout << endl << endl ;
  }
  
}