Cod sursa(job #409305)

Utilizator alexandru92alexandru alexandru92 Data 3 martie 2010 16:11:33
Problema Sortare prin comparare Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.01 kb
/*
 * File:   main.cpp
 * Author: virtualdemon
 *
 * Created on December 31, 2009, 7:28 PM
 */
#include <vector>
#include <fstream>
#include <iterator>

/*
 *
 */
using namespace std;
vector<int> v;
int size_threshold;
inline void swap( int x, int y )
{
    v[x]+=v[y];
	v[y]=v[x]-v[y];
	v[x]-=v[y];
}
void siftdown( int s, int e )
{
    int w=2*s+1;
    while( w < e )
    {
        if( w+1 < e && v[w+1] > v[w] )
            ++w;
        if( v[w] <= v[s] )
            return;
        swap( s, w );
        s=w;
        w=2*s+1;
    }
}
void downheap( int s, int e )
{int r=2*s+1;
    while( r < e )
    {
        if( r+1 < e && v[r] < v[r+1] ) ++r;
        if( v[r] <= v[s] ) return; //has heap structure
        swap( r, s );
        s=r;
        r=2*s+1;
    }
}
void HeapSort( int s, int e )
{
    for( int w=e/2-1; w > s; --w )
        downheap( w, e ); //creat a  heap from the arrat v
    downheap( s, e );
    for( e=e-1; e > s; --e )
    {
        swap( s, e );
        downheap( s, e );
    }
}
inline int medianof3( int left, int middle, int right )
{
    if( v[left] > v[middle] )
        swap( left, middle );
    if( v[left] > v[right] )
        swap( left, right );
    if( v[middle] > v[right] )
        swap( middle, right );
    swap( middle, right-1 );
    return v[right-1];
}
int Partition( int left, int right, int pValue )
{
    int leftPtr=left, rightPtr=right;
    while( true )
    {
        while( v[++leftPtr] < pValue );
        while( v[--rightPtr] > pValue );
        if( leftPtr >= rightPtr )
            break;
        swap( leftPtr, rightPtr );
    }
    swap( left, right-1 );
    return leftPtr;
}
void Introsort_Loop( int left, int right, int depth_limit )
{
    while( right-left > size_threshold )
    {
        if( !depth_limit )
        {
            HeapSort( left, right );
            return;
        }
        --depth_limit;
        int p=Partition( left, right, medianof3( left, left+(right-left)/2-1, right-1 ) );
        Introsort_Loop( p, right, depth_limit );
        right=p;
    }
}
void Insertion_Sort( int left, int right )
{int key, j;
    for( left+=1; left < right; ++left )
    {
        key=v[left];
        for( j=left-1; j >=0 && v[j] > key; --j )
            v[j+1]=v[j];
        v[j+1]=key;
    }
}
inline int Log2( int n)
{
  int pos = 0;
  if (n >= 1<<16) { n >>= 16; pos += 16; }
  if (n >= 1<< 8) { n >>=  8; pos +=  8; }
  if (n >= 1<< 4) { n >>=  4; pos +=  4; }
  if (n >= 1<< 2) { n >>=  2; pos +=  2; }
  if (n >= 1<< 1) {           pos +=  1; }
  return ((n == 0) ? (-1) : pos);
}
int main()
{int n;
    ifstream in("algsort.in");
    in>>n;
    copy( istream_iterator<int>(in), istream_iterator<int>(), back_inserter(v) );
    size_threshold=16;
    /*Introsort start here*/
    Introsort_Loop( 0, n, 2*Log2(n) );
    Insertion_Sort( 0, n );
    /*end here*/
     ofstream out("algsort.out");
    copy( v.begin(), v.end(), ostream_iterator<int>(out, " " ) );
    return 0;
}