Sunteți pe pagina 1din 6

Inițiere în Algoritmi Lecția 6 Alt algoritm de ordonare.

Sortarea prin selecție

Lecția 6. Alt algoritm de ordonare. Sortarea prin selecție

La această lecție vei afla:

 Ce este sortarea prin selecție


 Cum să o programezi
 De ce este considerată „mai bună” decât sortarea prin metoda bulelor

Ce este sortarea prin selecție?

Sortarea prin selecție este expresia modului firesc de ordonare a


obiectelor, folosit în activitățile cotidiene. Fie că dorești să ordonezi
cărțile de pe un raft după înălțime, astfel încât cele mai înalte cărți să
se afle în partea din dreapta a raftului. Nu vei compara înălțimile
pentru fiecare pereche de cărți. Vizual, vei căuta cartea cu cea mai
mare înălțime și o vei schimba cu locul cu cea mai din dreapta carte
de pe raft.
Apoi, vei repeta același procedeu pentru cărțile neordonate încă,
ignorând cartea, care este deja la locul său. Din nou, vei căuta cartea
cu cea mai mare înălțime, iar după ce o vei găsi, o vei schimba cu
locul ce ultima (cea mai din dreapta) dintre cărțile încă neordonate!
Acum, în partea din dreapta a raftului vei avea deja două cărți cu
cele mai mari înălțimi, aranjate corect.
Repeți procedeul încă odată. Cea de a treia cea mai înaltă carte
ajunge la locul său, după ce o găsești printre cărțile neordonate încă
și o schimbi cu locul cu ultima dintre cărțile neordonate...
Dacă pe raft sunt n cărți, procedeul se va repeta de n-1 ori până
când toate cărțile vor ajunge fiecare la locul său. Ultima carte se va
așeza ”singură” , deoarece fiecare dintre celelalte cărți deja ocupă în
acel moment locul corect.
Astfel, toate cărțile de pe raft au fost ordonate după înălțime (e
mai logic că le ordonăm alfabetic, după autor, dar nu va fi vizibil
rezultatul  ), dar numărul de permutări ale cărților va fi cu mult mai
mic decât dacă am modela aranjarea acestora folosind algoritmul din
lecția precedentă. Prin urmare, ne putem aștepta la o sortare mai
rapidă în acest caz!
Inițiere în Algoritmi Lecția 6 Alt algoritm de ordonare. Sortarea prin selecție

Algoritm:

Algoritmul sortării prin selecție este descris foarte simplu:

Fie că avem un tablou a cu n elemente, având valorile


a[1], a[2],..., a[j], a[j+1], ..., a[n].

Elementele de la a[1] până la a[j] încă nu sunt ordonate, în timp ce elementele a[j+1], ...,
a[n] formează un șir de valori ordonate crescător.

Mai mult, toate valorile elementelor a[1], a[2],..., a[j] nu depășesc valoarea elementului
a[j+1].

Atunci, se parcurg toate valorile elementelor de la a[1] până la a[j] inclusiv, căutându-se printre ele
elementul cu valoarea maximală. După se este determinat, acesta se schimbă cu locul cu elementul din
poziția j : a[j].

Acum numărul elementelor neordonate s-a micșorat cu 1, în timp ce un element a fost ”așezat” în
poziția corectă. Respectiv, se poate spune că j – indicele ultimului element încă neordonat, s-a micșorat
cu 1!

Procedura descrisă se repetă până când numărul j al elementelor încă neordonate nu va deveni egal cu
1.

Evident, la începutul algoritmului se consideră că j are valoarea n – toate elementele din tablou
formează fragmentul neordonat, în timp ce fragmentul ordonat nu conține nici un element.

Mai strict, algoritmul este descris pe pași în felul următor:

Pas 1. j⟵n
Pas 2. Dacă j>1 trecem la Pas 3, altfel trecem la Pas 6

Pas 3. max ⟵ a [ 1 ] , pmax ⟵1

Pas 4. Pentru toți i de la 1 la j verificăm


dacă a [ i ] > max atunci max ⟵ a [ i ] , pmax ⟵i

Pas 5. Schimbăm cu locul a [ j ] , a[ pmax], j ⟵ j−1 , revenim la Pas 2

Pas 6. STOP, valorile din tabloul a au fost ordonate ascendent.


Inițiere în Algoritmi Lecția 6 Alt algoritm de ordonare. Sortarea prin selecție

Tradițional includem librăria pentru citirea și


afișarea datelor (linia 1), declarăm variabilele
(linia 3).

Urmează descrierea funcției de afișare a


tabloului, (liniile 5 - 10) care primește în calitate
de parametru adresa tabloului de afișat și
numărul curent de elemente în tablou.

Elementul principal al programuli este funcția


care modelează algoritmul de sortare prin
selecție – selsort (liniile 12 - 29)

Linia 15 – modelează modificarea numărului de


elemente j în fragmentul încă nesortat – de la n
la 1. Instrucțiunile subordonate inițializează
elementul cu valoarea maximală și poziția lui
(linia 17), caută elementul cu valoare maximală
între elementele cu indicii cuprinși între 1 și j
(exact acele elemente care formează
fragmentul încă nesortat) (liniile 18 - 23),
schimbă cu locul elementul cu valoare
maximală cu ultimul dintre elementele din
fragmentul nesortat (liniile 24 -26)

Funcția main are o structură clasică: citește


datele inițiale (liniile 33 - 35), afișează
elementele tabloului până la sortare (linia 36),
apelează funcția de sortare prin selecție selsort
(linia 37) și afișează repetat elementele
tabloului după sortare (linia 38).

Extensie: de ce ”BUBBLESORT” e mai lentă?

Am spus anterior că sortarea prin metoda bulelor presupune un număr mare de interschimbări a
valorilor elementelor, ceea ce înseamnă mai multe operații, și, respectiv, mai mult timp.
Sortarea prin selecție, pentru fiecare element ”poziționat corect” efectuiază o singură
interschimbare a elementelor. Astfel, numărul de operații se micșorează, iar odată cu el – și timpul de
sortare. În următoarele lecții vom discuta despre algoritmi de sortare cu mult mai rapizi și decât
algoritmul de sortare prin selecție, dar aceștia au o cu totul altă organizare!
În continuare poți analiza un program simplu, care compară timpul de sortare pentru metoda bulelor
și sortarea prin selecție pe seturi identice de date. Valorile sortate sunt generate aleator, numărul lor
fiind egal cu 50000!
Inițiere în Algoritmi Lecția 6 Alt algoritm de ordonare. Sortarea prin selecție

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

int a[100000], b[100000];


int n;

struct timeval start, stop; // variabile pentru masurarea timpului

double secs (struct timeval start, struct timeval stop)


// transforma diferenta de timp de la inceputul sortarii
// pana la sfarsitul ei in secunde
{
return (double)(stop.tv_usec - start.tv_usec) / 1000000 +
(double)(stop.tv_sec - start.tv_sec);
}

void bubblesort(int *x, int n) // algoritmul bubblesort


{
int flag;
do
{
flag = 0;
for (int i = 0; i < n - 1; i++)
if (x[i] > x[i + 1] )
{
int tmp = x[i];
x[i] = x[i + 1];
x[ i + 1] = tmp;
flag = 1;
}
} while (flag == 1 );

return;
}

void selection_sort(int *x, int n) // algoritmul de sortare prin selectie


{
int max, pmax, tmp;

for (int j = n - 1; j > 0; j--)


{
max = x[0]; pmax = 0;
for (int i = 0; i <= j; i++)
if( max < x[i])
{
max = x[i];
pmax = i;
}
tmp = x[pmax]; x[pmax] = x[j]; x[j] = tmp;
Inițiere în Algoritmi Lecția 6 Alt algoritm de ordonare. Sortarea prin selecție

}
return;
}

int main()
{
// introducere date
srand(time(0)); // initializarea regimului de generare a numerelor aleatoare
n = 50000;
for (int i = 0; i < n; i++) b[i] = a[i] = rand() % 100;
gettimeofday(&start, NULL); //se preia timpul in momentul inceperii sortarii
selection_sort(a,n);
gettimeofday(&stop, NULL); //se preia timpul in momentul sfirsitului sortarii
printf("\n timp pentru sortarea prin selectie - %f\n", secs(start, stop));
// la fel - pentru sortarea prin metoda bulelor
gettimeofday(&start, NULL);
bubblesort(b,n);
gettimeofday(&stop, NULL);
printf("\n timp pentru sortarea prin metoda bulelor - %f\n", secs(start, stop));
return 0;
}

Analizează programul. Modifică numărul de elemente sortate, diapazonul de valori ale elementelor.
După fiecare modificare lansează programul din nou și compară timpii de sortare.
Inițiere în Algoritmi Lecția 6 Alt algoritm de ordonare. Sortarea prin selecție

Cod program sortare prin selecție

#include <stdio.h>

int a[100], n, t, k;

void afisaretablou(int *x, int n)


{
for (int i = 1; i <= n; i++) printf("%d ", x[i]);
printf("\n");
return;
}

void selsort(int *x, int n)


{
int max, pmax, tmp;
for (int j = n ; j > 1; j--)
{
max = x[1]; pmax = 1;
for (int i = 1; i <= j; i++)
if( max < x[i])
{
max = x[i];
pmax = i;
}
tmp = x[j];
x[j] = x[pmax];
x[pmax] = tmp;
}
return;
}

int main()
{
scanf("%d", &n);
for (int i = 1; i <= n ; i++)
scanf("%d", &a[i]);
afisaretablou(a, n);
selsort(a, n);
afisaretablou(a, n);
return 0;
}

S-ar putea să vă placă și