//----------------------------------------------------------------------
//  IMPLEMENTATION FILE (qsort2.cpp)
//  This module exports a function to sort an integer vector
//  into ascending order.
//----------------------------------------------------------------------
#include "qsort2.h"

//  Algorithm: improved version of quicksort

void Quicksort( /* inout */ int vec[],
                /* in */    int loBound,
                /* in */    int hiBound )
    //..................................................................
    // PRE:  loBound < hiBound  (i.e., at least 2 items to sort)
    //    && Assigned(vec[loBound..hiBound])
    // POST: vec[loBound..hiBound] contain same values as
    //       at invocation but are sorted into ascending order
    //..................................................................
{
    int pivot;
    int loSwap;
    int hiSwap;
    int temp;

    if (hiBound-loBound == 1) {             // Two items to sort
        if (vec[loBound] > vec[hiBound]) {
            temp = vec[loBound];
            vec[loBound] = vec[hiBound];
            vec[hiBound] = temp;
        }
        return;
    }
    pivot = vec[(loBound+hiBound)/2];       // 3 or more items to sort
    vec[(loBound+hiBound)/2] = vec[loBound];
    vec[loBound] = pivot;
    loSwap = loBound + 1;
    hiSwap = hiBound;
    do {
        while (loSwap <= hiSwap && vec[loSwap] <= pivot)
                            // INV (prior to test):
                            //    All vec[loBound+1..loSwap-1]
                            //    are <= pivot  &&  loSwap <= hiSwap+1
            loSwap++;
        while (vec[hiSwap] > pivot)
                            // INV (prior to test):
                            //    All vec[hiSwap+1..hiBound]
                            //    are > pivot  &&  hiSwap >= loSwap-1
            hiSwap--;
        if (loSwap < hiSwap) {
            temp = vec[loSwap];
            vec[loSwap] = vec[hiSwap];
            vec[hiSwap] = temp;
        }
        // INV: All vec[loBound..loSwap-1] are <= pivot
        //   && All vec[hiSwap+1..hiBound] are > pivot
        //   && (loSwap < hiSwap) --> vec[loSwap] <= pivot < vec[hiSwap]
        //   && (loSwap >= hiSwap) --> vec[hiSwap] <= pivot
        //   && loBound <= loSwap <= hiSwap+1 <= hiBound+1
    } while (loSwap < hiSwap);
    vec[loBound] = vec[hiSwap];
    vec[hiSwap] = pivot;

    if (loBound < hiSwap-1)            // 2 or more items in 1st subvec
        Quicksort(vec, loBound, hiSwap-1);

    if (hiSwap+1 < hiBound)            // 2 or more items in 2nd subvec
        Quicksort(vec, hiSwap+1, hiBound);
}


