//  File: quicksort.C
//
//  Quicksort Routines

#include <assert.h>
#include <iostream.h>
#include <iomanip.h>
#include "array.h"
#include "sorts.h"

// Local function prototypes
//
static int partition(Array& A, int low, int high) ;
static void RecQuickSort(Array& A, int low, int high) ;

static int partition(Array& A, int low, int high) {
   DATA x, temp ;
   int i, j ;
   
   i = low - 1;  
   j = high + 1;
   x = A[low] ;
  
   while (true) {

      // Find an element less than x 
      do {
         j = j - 1;
      } while (A[j] > x) ; 
      
      // Find an element greater than x
      do {
         i = i + 1;
      } while (A[i] < x);
                                
      // swap smaller and bigger elements, if needed
	  //
      if (i < j) {
         temp = A[j] ;
         A[j] = A[i] ;
         A[i] = temp ;
      } else {
         return j;
      }
    }
}


static void RecQuickSort(Array& A, int low, int high) {
   int q ;

#ifndef NDEBUG
   cout << "QuickSort: low = " << low << ", high = " << high << endl ;
#endif

   if (low >= high) return ;
   
   q = partition(A, low, high) ;
   assert(q < high) ;

   RecQuickSort(A, low, q) ;
   RecQuickSort(A, q + 1, high) ;
}


void QuickSort(Array& A) {

   RecQuickSort(A, 0, A.length()-1) ;
}
