Cod sursa(job #2082419)

Utilizator VoineaAndreiVoinea Ioan-Andrei VoineaAndrei Data 6 decembrie 2017 09:57:05
Problema Sortare prin comparare Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 4.08 kb
#include<bits/stdc++.h>
using namespace std;

ifstream f("algsort.in");
ofstream g("algsort.out");

int n;

////////MERGE SORT
void merge_sort(vector<int>&v,int s,int d){

    if(s==d) return;

    //mijlocul
    int mij=(s+d)/2;

    //apelare recursiva
    merge_sort(v,s,mij);
    merge_sort(v,mij+1,d);

    int st=s,dr=mij+1;
    vector<int>aux;

    //sortam vectorul cu ajutorul unui auxiliar
    while(st<mij+1||dr<=d){
            if(st==mij+1) {
                aux.push_back(v[dr]);
                ++dr;   }
            else if(dr==d+1) {
                aux.push_back(v[st]);
                ++st;      }
            else {
                if(v[st]>v[dr]) {
                    aux.push_back(v[dr]);
                    ++dr;       }
                else            {
                    aux.push_back(v[st]);
                    ++st;       }
                 }
}
            for(int i=s;i<=d;++i)
                v[i]=aux[i-s];
}

//////////////////




////////RADIX SORT

//cheia de sortare pentru counting sort si anume cea mai putin importanta cifra
int key(int x,int n){
    while(n>1) {x/=10;n--;}
    return x%10;
}

//o functie care determina cate cifre are cel mai mare numar
int nr_cif_max(vector<int>v){
    int k=0,kmax=-1;;
    for(int i=0;i<n;++i) {
            k=0;
            while(v[i]>0) {v[i]/=10;++k;}
            if(k>kmax) kmax=k;
    }
    return k;
}

//counting sort
void counting_sort(vector<int>&v,int p){

    //vectorul de "chei" ce reprezinta ce mai putin importanta cifra
    vector<int>cnt(10);

    //un vector clona
    vector<int>v2;

    //clonam vectorul si numaram numarul de aparitii a unei cifre
    for(int i=0;i<n;++i) {
            v2.push_back(v[i]);
            if(key)
            ++cnt[key(v[i],p)];
    }

    //parcurgem vectorul de chei si retinem numarul de aparitii
    //a fiecariei cifre in raportul cu celelalte aparitii
    int nr=0,aux;
    for(int i=0;i<10;++i){
        aux=cnt[i];
        cnt[i]=nr;
        nr+=aux;
    }

    //stiind ca elementul x are k-1 elemente inainte inseamna
    // ca acesta va fi pe pozitia k
    for(int i=0;i<n;++i) {
            v[cnt[key(v2[i],p)]]=v2[i];
            ++cnt[key(v2[i],p)];
    }
}

//radix sort foloseste counting sort repetat pentru a sorta vectorul
//cu ajutorul celei mai putin importante cifre
void radix_sort(vector<int>&v){
    int k=nr_cif_max(v);
    for(int i=1;i<=k;i++)
        counting_sort(v,i);

}

//////////////////




/////////QUICKSORT
void quicksort(vector<int>&v,int s,int d){

    if (s==d) return;

    //pivot generat random, fiind medianul dintre 3 pivoturi random
    int p1,p2,p3,pivot=0;
    p1=rand()%(d-s+1) +s;
    p2=rand()%(d-s+1) +s;
    p3=rand()%(d-s+1) +s;
    if( (v[p1]-v[p2]>0 && v[p1]-v[p3]<0) ||(v[p1]-v[p2]<0 && v[p1]-v[p3]>0) ) pivot=p1;
    else if( (v[p2]-v[p1]>0 && v[p2]-v[p3]<0) ||(v[p2]-v[p1]<0 && v[p2]-v[p3]>0) ) pivot=p2;
    else pivot=p3;

    //un vector auxiliar pentru valorile < ca pivot si un deque pentru cele >=
    vector<int>aux;
    deque<int>q;

     for(short int i=s;i<=d;++i) {
         if(v[i]<v[pivot]) {
            aux.push_back(v[i]);
         }
         else if(v[i]==v[pivot]) q.push_front(v[i]);  //daca e egal il punem la inceput pentru a-l scoate primul
         else
            q.push_back(v[i]);
     }

    //next_d reprezinta pozitia unde a fost impartit in 2 vectorul
    int next_d;
    next_d=s+aux.size();

    //copiem din aux si q in v
    int siz=q.size();
    for(int i=0;i<aux.size()+siz;++i){
           if(i<aux.size())v[s+i]=aux[i];
           else {v[s+i]=q.front();q.pop_front();}
           }
    //se apeleaza recursiv
    quicksort(v,s,next_d);
    if(next_d+1<d)
    quicksort(v,next_d+1,d);
}

//////////////////




int main(){

    srand(time(NULL));//pentru qsort

    f>>n;
    vector<int>v(n);
    for(int i=0;i<n;++i)
        f>>v[i];

    //merge_sort(v,0,n-1);
    //radix_sort(v);
    quicksort(v,0,n-1);

    for(int i=0;i<n;++i)
        g<<v[i]<<" ";

}