Cod sursa(job #353565)

Utilizator alexandru92alexandru alexandru92 Data 5 octombrie 2009 16:37:37
Problema Sortare prin comparare Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.34 kb
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <iterator>
#include <algorithm>
#define InFile "algsort.in"
#define OutFile "algsort.out"

/*
 *
 */

using namespace std;
ifstream in;
ofstream out;
class IntroSort
{
    unsigned *v;
    unsigned size, till;
    inline void swap( unsigned, unsigned );
    inline unsigned medianof3( unsigned, unsigned, unsigned );
    void downheap( unsigned, unsigned );
    void make_heap( unsigned, unsigned );
    unsigned partition( unsigned, unsigned, unsigned );
public:
    IntroSort();
    ~IntroSort();
    void push( istream& );
    void output( ostream& );
    inline unsigned getsize();
    void HeapSort( unsigned, unsigned );
    void introsort( unsigned, unsigned, unsigned  );
    void InsertionSort( unsigned, unsigned );
};
IntroSort::IntroSort()
{till=size=0;  //there is no element in vector
    v=(unsigned*)malloc( sizeof( unsigned ) ); // give memory
}
IntroSort::~IntroSort()
{
    free(v); //free the memory
}
void IntroSort::push( istream& in )
{++size; // a new element is inserted
    v=(unsigned*)realloc( (void*)v, size*sizeof( unsigned ) ); // creating enough space for one more element
    in>>v[size-1]; //reading date
}
void IntroSort::output( ostream& out )
{
   copy( v, v+size, ostream_iterator< unsigned >( out, " " ) ); // outputing the array
}
inline unsigned IntroSort::getsize()
{
    return size;
}
inline void IntroSort::swap( unsigned a, unsigned b ) // exchanging 2 element v[a] and v[b]
{unsigned aux=v[a];
    v[a]=v[b];
    v[b]=aux;
}
/*              Median of three
a>b|         true        |       false
---+---------------------+----------------------
b>c| true |     false    | true         | false
---+---------------------+----------------------
a>c|  X   | true | false | true | false |  X
---+---------------------+----------------------
   |  b   |  c   |  a    |  a   |  c    |  b
*/
inline unsigned IntroSort::medianof3( unsigned a, unsigned b, unsigned c )
{
    if( v[a] > v[b] )
    {
        if( v[b] > v[c] )
          return v[b];
        else if( v[a] > v[c] )
               return v[c];
        return v[a];
    }
    else if( v[b] > v[c] )
         {
             if( v[a] > v[c] )
               return v[a];
             else return v[c];
         }
    return v[b];
}
unsigned IntroSort::partition( unsigned st, unsigned dr, unsigned x )
{
    while( true )
    {
        while( v[st] <= x ) ++st;
        --dr;
        while( x <= v[dr] ) --dr;
        if( !( st < dr ) )
          return st;
        swap( st, dr );
        ++st;
    }
}
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; // if it is heap stop
        swap( root, begin );
        begin=root;
        root=2*begin+1;
    }
}
void IntroSort::make_heap( unsigned start, unsigned end )
{
    for( unsigned begin=end/2-1; begin > start; --begin )
       downheap( begin, end );
    downheap( start, end );
}
void IntroSort::HeapSort( unsigned begin, unsigned end )
{
    make_heap( begin, end );
    for( end=end-1; end > begin; --end )
    {
        swap( begin, end );
        downheap( begin, end );
    }
    swap( begin, end );
    downheap( begin, end );
}

void IntroSort::introsort( unsigned st, unsigned dr, unsigned depth_limit )
{
    while( dr - st > till )
    {
        if( !depth_limit )
        {
            HeapSort( st, dr );
            return ;
        }
        --depth_limit;
        unsigned m=partition( st, dr, medianof3( st, st+(dr-st)/2+1, dr-1 ) );
        introsort( m, dr, depth_limit );
        dr=m;
    }
}
void IntroSort::InsertionSort( unsigned st, unsigned dr )
{
    unsigned i, j, aux;
    for( i=st; i < dr; ++i )
    {
        j=i;
        aux=v[i];
        while( j != st && aux < v[j-1] )
        {
            v[j]=v[j-1];
            --j;
        }
        v[j]=aux;
    }
}
int main()
{int N;
 IntroSort a;
    in.open( InFile );
    in>>N;
    while( N-- )
    {
        a.push( in );
    }
    out.open( OutFile );
    a.introsort( 0, a.getsize(), log(a.getsize())/log(2) );
    a.InsertionSort( 0, a.getsize() );
    a.output( out );
    return EXIT_SUCCESS;
}