Cod sursa(job #354508)

Utilizator alexandru92alexandru alexandru92 Data 8 octombrie 2009 16:22:04
Problema Sortare prin comparare Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.87 kb
/* 
 * 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;
}