/*
* File: main.cpp
* Author: speedemon
*
* Created on October 7, 2009, 3:04 PM
*/
#include <cmath>
#include <fstream>
#include <cstdlib>
#define InFile "algsort.in"
#define OutFile "algsort.out"
using namespace std;
ifstream in;
ofstream out;
class IntroSort
{
unsigned *v;
unsigned size;
inline void swap( int, int );
inline unsigned medianof3( unsigned, unsigned, unsigned );
void downheap( unsigned, unsigned );
void HeapSort( unsigned, unsigned );
inline void QSort( int, int );
inline void introsort( int, int, int );
void InsertionSort( unsigned, unsigned );
public:
IntroSort();
~IntroSort();
inline void push( istream& );
void output( ostream& );
inline void sort();
};
IntroSort::IntroSort()
{size=0;
v=new unsigned;
}
IntroSort::~IntroSort()
{
delete[] v;
}
inline void IntroSort::push( istream& in )
{++size;
v=(unsigned*)realloc( (void*)v, size*sizeof( unsigned ) );
in>>v[size-1];
}
void IntroSort::output( ostream& out )
{
for( unsigned i=0; i < size; ++i ) out<<v[i]<<' ';
}
inline void IntroSort::swap( int a, int b )
{unsigned aux=v[a];
v[a]=v[b];
v[b]=aux;
}
inline unsigned IntroSort::medianof3( unsigned a, unsigned b, unsigned c )
{
if( v[a] > v[b] )
{
if( v[b] > v[c] )
return b;
else if( v[a] > v[c] )
return c;
else return a;
}
else if( v[b] > v[c] )
{
if( v[a] > v[c] )
return a;
else return c;
}
return b;
}
void IntroSort::downheap( unsigned begin, unsigned end )
{
for( unsigned root=2*begin+1; root < end; )
{
if( root+1 < end && v[root] < v[root+1] ) ++root;
if( v[root] <= v[begin] ) return;
swap( root, begin );
begin=root;
root=2*begin+1;
}
}
void IntroSort::HeapSort( unsigned begin, unsigned end )
{
for( unsigned w=end/2-1; w > begin; --w )
downheap( w, end );
downheap( begin, end );
for( end-=1; end > begin; --end )
{
swap( begin, end );
downheap( begin, end );
}
swap( begin, end );
downheap( begin, end );
}
inline void IntroSort::QSort( int left, int right )
{
if( right <= left )
return ;
unsigned x=v[left];
int i=left+1, j=right;
while( i <= j )
{
while( i <= j && v[i] <= x )
++i;
while( i <= j && x <= v[j] )
--j;
if( i > j || i > right || j < left )
break;
swap( i, j );
}
--i;
v[left]=v[i];
v[i]=x;
QSort( left, i-1 );
QSort( i+1, right );
}
inline void IntroSort::introsort( int left, int right, int depth_limit )
{
if( right-left >= 16 )
{
if( !depth_limit )
{
HeapSort( left, right );
return;
}
--depth_limit;
unsigned pIndex=medianof3( left, left+(right-left)/2+1, right-1 );
unsigned pValue=v[pIndex],sIndex=left;
swap( pIndex, right );
for( unsigned i=left; i < right; ++i )
if( v[i] <= pValue )
{
swap( i, sIndex );
++sIndex;
}
swap( sIndex, right );
introsort( left, sIndex-1, depth_limit );
introsort( sIndex+1, right, depth_limit );
}
}
void IntroSort::InsertionSort( unsigned begin, unsigned end )
{
unsigned i, j;
unsigned aux;
for( i=begin; i <end; ++i )
{
j=i;
aux=v[i];
while( j != begin && aux <= v[j-1] )
{
v[j]=v[j-1];
--j;
}
v[j]=aux;
}
}
inline void IntroSort::sort()
{
//HeapSort( 0, size ); // 100pct
QSort( 0, size-1 ); // 60 pct, 2xTLE
// introsort( 0, size-1, size ); //with HeapSort takes 100pct
//HeapSort( 0, size );
//InsertionSort( 0, size ); //with insertionsort takes 60pct
}
int main()
{int N;
IntroSort a;
in.open( InFile );
in>>N;
while( N-- )
{
a.push( in );
}
out.open( OutFile );
a.sort();
a.output( out );
return 0;
}