// main.cpp
// heapify
// vs 20xx
#include "stdafx.h"
#include <stdio.h>
#define PARENT(X) ((X) / 2)
#define LEFT(X) ((X) * 2)
#define RIGHT(X) ((X)*2 + 1)
// Exchage in bitwise
#define SWAP(X, Y) ((X) ^= (Y) ^= (X) ^= (Y))
// Take place in data array
#define    HOLDER    0
void max_heapify(int arr[], size_t cur, size_t len)
{
    // All swap operations are done by index
    size_t l = LEFT(cur) ;
    size_t r = RIGHT(cur) ;
    size_t largest = cur ;
    // Heapify
    if (l < len && arr[largest] < arr[l])
    {
        largest = l ;
    }//if
    if (r < len && arr[largest]  < arr[r])
    {
        largest = r ;
    }//if
    // Heapify Recursively if needed
    if (largest != cur)
    {
        // Exchage 'arr[largest]' & 'arr[cur]'
        SWAP(arr[cur], arr[largest]) ;
        // Here is the beauty in the heap
            // the operation grow in 2^n !
        max_heapify(arr, largest, len) ;
    }//if
    return ;
}
void build_max_heap(int arr[], size_t len)
{
    for (size_t i = 0 ;i < (len-1)/2 ;++i)
    {
        max_heapify(arr, PARENT(len) - i, len) ;
    }//for
}
void heap_sort(int arr[], size_t len)
{
    for (size_t i = 0 ;i < len - 1 ;++i)
    {
        // Exchage the first & last elements
        SWAP(arr[1], arr[len - i - 1]) ;
        // Reheapify the new array
        max_heapify(arr, 1, len - i - 1) ;
    }//for
}
void Show(int arr[], size_t len)
{
    for (size_t i = 1 ;i < len ;++i)
    {
        printf("%d ", arr[i]) ;
    }//for
    printf("\n") ;
}
int arr[] = {HOLDER, 4, 2, 6, 5, 0, 7, 9, 1, 8, 3} ;
int main()
{
    build_max_heap(arr, sizeof(arr) / sizeof(arr[0])) ;
    Show(arr, sizeof(arr) / sizeof(arr[0])) ;
    heap_sort(arr, sizeof(arr) / sizeof(arr[0])) ;
    Show(arr, sizeof(arr) / sizeof(arr[0])) ;
    return 0 ;
}