#include <iostream>
#include <math.h>
static int length;
static int Heap_Size;
inline int Left( int &i )
{
return 2*i;
}
inline int Right( int &i )
{
return 2*i+1;
}
inline int Parent( int &i )
{
return floor(i/2);
}
inline int Heap_Maximum( int *A )
{
return A[1];
}
void Max_Heapify( int *A, int i )
{
int l,r,largest;
l = Left(i);
r = Right(i);
if( l <= Heap_Size && A[l] > A[i] )
largest = l;
else
largest = i;
if( r <= Heap_Size && A[r] > A[largest] )
largest = r;
if( largest != i )
{
int temp = A[i];
A[i] = A[largest];
A[largest] = temp;
Max_Heapify( A, largest );
}
}
void Min_Heapify( int *A, int i )
{
int l,r,smallest;
l = Left(i);
r = Right(i);
if( l <= Heap_Size && A[l] < A[i] )
smallest = l;
else
smallest = i;
if( r <= Heap_Size && A[r] < A[smallest] )
smallest = r;
if( smallest != i )
{
int temp = A[i];
A[i] = A[smallest];
A[smallest] = temp;
Min_Heapify( A, smallest );
}
}
void Build_Max_Heap( int *A )
{
Heap_Size = length;
for( int i = floor(length/2); i >= 1; --i )
{
Max_Heapify( A, i );
}
}
void Build_Min_Heap( int *A )
{
Heap_Size = length;
for( int i = floor(length/2); i >= 1; --i )
{
Min_Heapify( A, i );
}
}
int Heap_Extract_Max( int *A )
{
if( Heap_Size < 1 )
{
std::cout << " heap underflow " << std::endl;
return -1;
}
int max = A[1];
A[1] = A[Heap_Size];
Heap_Size--;
Max_Heapify( A, 1 );
return max;
}
void Heap_Increase_Key( int *A, int i, int key )
{
if( key < A[i] )
{
std::cout << " new key is smaller than current key " << std::endl;
return;
}
A[i] = key;
while( i > 1 && A[Parent(i)] < A[i] )
{
int temp = A[i];
A[i] = A[Parent(i)];
A[Parent(i)] = temp;
i = Parent(i);
}
}
void Max_Heap_Insert( int *A, int key )
{
Heap_Size++;
A[Heap_Size] = -INFINITY;
Heap_Increase_Key( A, Heap_Size, key );
}
void print( int *A, int n )
{
for( int i = 1; i <= n; i++ )
{
std::cout << A[i] << " ";
}
std::cout << std::endl;
}
int main( int argc, char* argv[] )
{
std::cout << " input the length of the array: ";
std::cin >> length;
int *A;
A = new int[length+1];
for( int i = 1; i < length+1; i++ )
{
std::cin >> A[i];
}
Build_Max_Heap(A);
print( A, length );
int flag = -1;
std::cout << " 0. quit " << std::endl;
std::cout << " 1. maximum " << std::endl;
std::cout << " 2. insert " << std::endl;
std::cout << " 3. extract " << std::endl;
std::cout << " 4. increase " << std::endl;
std::cin >> flag;
while( flag != 0 )
{
switch( flag ) {
case 1:
{
std::cout << Heap_Maximum( A ) << std::endl;
break;
}
case 2:
{
int key;
std::cin >> key;
Max_Heap_Insert( A, key );
print( A, Heap_Size );
break;
}
case 3:
{
std::cout << Heap_Extract_Max( A ) << std::endl;
print( A, Heap_Size );
break;
}
case 4:
{
int i,key;
std::cin >> i >> key;
Heap_Increase_Key( A, i, key );
print( A, Heap_Size );
break;
}
default:
break;
}
std::cout << " 0. quit " << std::endl;
std::cout << " 1. maximum " << std::endl;
std::cout << " 2. insert " << std::endl;
std::cout << " 3. extract " << std::endl;
std::cout << " 4. increase " << std::endl;
std::cin >> flag;
}
return 0;
}