Pagini recente » Cod sursa (job #3150062) | Cod sursa (job #3122708) | Cod sursa (job #558558) | Cod sursa (job #2686297) | Cod sursa (job #1758194)
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define nmax 500003
ifstream in("algsort.in");
ofstream out("algsort.out");
//////////////////////////////
///////////
/////////// LSD Radix sort using countsort for bytes
///////////
//////////////////////////////
#define max_n 10000000+1
int v[max_n],temp[max_n];
const int max_byte = (1<<8)-1;//valoarea maxima a unui byte
const int nr_bytes = sizeof(int);//nr de bytes din un int
inline int ithbyte(int n,int i)//al i byte de la stanga la dreapta pentru numarul n
{
return (n>>(i*8))&max_byte;//un nr are 8 biti si vrem sa shiftam i bytes la dreapta deci i*8 si apoi
// facem & cu valoarea maxima a unui byte pentru a obtine doar al i-lea byte din numar
}
void byte_numsort(int *A, int *B,int n, int byte_nr)//folosim sortarea countsort modificata O(n+K) unde K e valoare maxima a unui byte
{ //pentru a sorta numerele in functie de al byte_nr-lea byte de la stanga la dreapta
int C[max_byte+1]; // C[i] nr de aparitii al byte-ului i in toate numerele
int index[max_byte+1]; //index[i] = numarul de numere care au al byte_nr -lea byte mai mic ca i
for(int i = 0 ; i <= max_byte ; i ++)
C[i] = 0; //initial nu avem bytes
for(int i = 0 ; i < n ; i ++)
C[ithbyte(A[i],byte_nr)]++; // pentru fiecare al byte_nr -lea byte din fiecare nr incrementam aparitia in C
index[0] = 0; //initial nu avem niciun byte < 0
for(int i = 1 ; i <= max_byte; i++)//pentru fiecare numar de la 0 la valorea maxima a unui byte
index[i] = index[i-1]+C[i-1];//numarul de bytes mai mici ca i va fi nr de aparitii al al i-1-lea byte in
// toate numerele + numarul de bytes mai mici ca i-1
for(int i = 0 ; i < n ; i++)//pentru fiecare numar vedem unde ii este locul in functie de valoarea celui
//de-al byte_nr -lea byte
{
B[index[ithbyte(A[i],byte_nr)]] = A[i];//deci index de un byte reprezinta pozitia valorii A[i] in vectorul B
index[ithbyte(A[i],byte_nr)]++;//si deoarece am asezat pe pozitia aceea deja o valoare crestem pozitia
}
for(int i = 0 ; i< n ; i++)
A[i] = B[i];//punem la loc in A valoriile in ordinea corespunazatoare
}
void LSD_byte_radixsort(int *v, int n)//sortam folosind LSD radix sort vectorul v cu n elemente de la 0 la n-1
{ //O(dn +dK) pentru unde d = numarul de bytes si K e valoarea maxima a unui byte
for(int i = 0 ; i< nr_bytes ; i++)//pentru fiecare byte
byte_numsort(v,temp,n,i);//sortam folosind countsort in functie de al i-ea byte de la dreapt la stanga
}
vector<int> bucket[10];//bucket vector de galeti si fiecare cifra de la 0...9 este o galeata unde bagam numerele cu aceea cifra
void LSD_digit_radixsort(int *v, int n)//LSD radix sort pentru cifre
{
int max_el = *max_element(v,v+n);//elementul maxim
int digits = 0;//numar de cifre maxime dintr-un numar
do{max_el/=10;digits++;}while(max_el);//aici le aflam
int pow10[10];//si pow10[i] va fi 10^i
pow10[0] = 1;
for(int i = 1 ; i <= 9 ; i++)
pow10[i] = pow10[i-1]*10;
int k;//pentru a baga inapoi in v din galeti valorile
for(int i = 0 ; i < digits ; i++)//pentru fiecare cifra de la dreapta la stanga unui numar
{
for(int j = 0 ; j < n ; j++)//pentru toate numerele
bucket[(v[j]/pow10[i])%10].push_back(v[j]);//bagam valoarea v[j] in galeata cu indexul = a i cifra de la dreapta
k = 0; //la stanga a numarului v[j] si obtime cifra cu formula (v[j]/pow10[i])%10
for(int j = 0 ; j <= 9 ; j++)//bagam numerele din fiecare galeata in ordine de la cea mai mica cifra la cea mai mare
{
for(const auto& nr:bucket[j])//pentru fiecare valoare din acceea galeata o bagam inapoi in vectorul v
v[k++] = nr;//pe pozitia corecta
bucket[j].clear();//si golim tot ce e in galeata
}
}
}
int main()
{
int n,i;
in >> n;
int v[n+5];
for( i = 0 ; i < n ; i++)
in >> v[i];
LSD_byte_radixsort(v,n);
for(int i = 0 ; i < n ; i ++)
out << v[i] << " ";
return 0;
}