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

//  Algorithm: heap sort

void Sort( /* inout */ int vec[],
           /* in */    int vSize )
    //..................................................................
    // PRE:  Assigned(vSize)  &&  Assigned(vec[0..vSize-1])
    // POST: vec[0..vSize-1] contain same values as
    //       vec[0..vSize-1]<entry> but are sorted into ascending order
    //..................................................................
{
    int i;
    int originalVal;
    int promoteIndx;
    int parentIndx;

    for (i = 1; i < vSize; i++) {
        originalVal = vec[i];
        promoteIndx = i;
        parentIndx = (promoteIndx-1) / 2;
        while (promoteIndx > 0 && vec[parentIndx] < originalVal) {
            vec[promoteIndx] = vec[parentIndx];
            promoteIndx = parentIndx;
            parentIndx = (promoteIndx-1) / 2;
        }
        vec[promoteIndx] = originalVal;
    }

    int bottom;
    int displacedVal;
    int vacantNodeIndx;
    int leftIndx;
    int rightIndx;
    int maxIndx;

    for (bottom = vSize-1; bottom > 0; bottom--) {
        displacedVal = vec[bottom];
        vec[bottom] = vec[0];
        // ASSERT: Value in root moved to current bottom of vec

        vacantNodeIndx = 0;
        while (TRUE) {
            leftIndx = 2*vacantNodeIndx + 1;
            if (leftIndx >= bottom)
                break;
            rightIndx = 2*vacantNodeIndx + 2;
            if (rightIndx >= bottom || vec[leftIndx] > vec[rightIndx])
                maxIndx = leftIndx;
            else
                maxIndx = rightIndx;
            if (vec[maxIndx] <= displacedVal)
                break;
            vec[vacantNodeIndx] = vec[maxIndx];
            vacantNodeIndx = maxIndx;
       }
       vec[vacantNodeIndx] = displacedVal;
       // ASSERT: Heap has been recreated in vec[0..bottom-1]
    }
}

