You are on page 1of 10

Curs 5 - Programarea calculatoarelor și limbaje de programare

Metode de sortare
1. Concepte generale

o Sortarea datelor este un pas important care trebuie să fie realizat înainte de aplicarea
altor algoritmi ca, de exemplu, a algoritmului de căutare.
o Mulţi cercetători în informatică au petrecut mult timp dezvoltând diverse metode de
sortare, deoarece aceşti algoritmi importanți în orice implementare, dar sunt și foarte
mari consumatori de timp.

Exemple de sortări:
 Sortare prin inserţie,
 Sortare prin selecţie,
 Sortare Bubble
 Sortare rapidă (quicksort)
 Sortare shell

2. Sortarea prin inserție

Să considerăm șirul:
S = {s1, s2, …, sn}
Format din elemente aparținând universului U. Scopul sortării este de a rearanja elementele
din S astfel încât să formăm un șir nou S’ în care elementele sunt în ordine.

Încercăm să formăm o serie de șiruri sortate S’0, S’1, S’2, …,S’n, astfel:
1. Primul șir sortat este mulțimea vidă S’0 : S’0 = {}.
2. Având șirul S’i în seria de șiruri sortate, următorul șir în serie este S’i+1, obținut prin
inserarea elementului (i+1) al șirului nesortat si+1 în poziția corectă în șirul S’i.

Fiecare șir S’i conține primele i elemente ale șirului nesortat S.


De aceea, șirul final S’n este exact șirul sortat pe care îl căutam: S’ = S’n.
Exemplu:

public void insertionSort(int myArray[], int number)


{
int initial, sort;
for (sort=1; sort < number; sort++) // number este numărul total de elemente
{
double temp = myArray[sort];
initial = sort;
while(initial>0 && myArray[initial-1] >= temp)
{
myArray[initial] = MyArray[initial-1];
--initial;
}
myArray[initial] = temp;
}
} // sfârșit insertionSort()
//sort este indexul elementelor și divide șirul în “sortat” și “nesortat”.
//Fiecare element sortat este pus în șirul sortat numit myArray.
//temp marchează elementul sortat la un anumit moment de timp
//initial este un fel de cursor care merge de la dreapta la stânga atunci când temp //este
mai mică decât valoarea curentă verificată.

Complexitatea acestui algoritm este: O(n2)

3. Sortarea prin selecție

La fiecare pas, se face o căutare liniară a elementelor nesortate pentru a se determina poziția
celui mai mare element rămas. Acest element este apoi mutat în poziția corectă a șirului prin
inversarea lui cu elementul ce ocupă respectiva poziție. Totodată există și varianta de căutare
a elementului minim ce se mută în poziția corespunzătoare:

void selectionSort(int myArray[], int number)


{
int i, j;
int min, temp;
for (i = 0; i < number-1; i++)
{
min = i; // i este minimum
for (j = i+1; j < number; j++)
{
if (myArray[j] < myArray[min])
min = j;
}
temp = myArray[i];
myArray[i] = myArray[min];
myArray[min] = temp;
}
}// sfârșit selectionSort()

Exemplu:
Complexitate: O(n2)

4. Sortarea bubble

 Pentru a sorta șirul S = {s0, s1, …, sn-1}, sortarea bubble face n-1 treceri pin șirul de date.
 La fiecare pas de trecere, elementele adiacente (alăturate) sunt comparate și inversate
dacă este cazul. Întâi sunt comparate s0 și s1 ,apoi s1 și s2 etc.
 După prima trecere prin șirul de date, cel mai mare element este practic împins pin
șir, până în ultima poziție a acestuia.
 În general, după k treceri prin șirul de date, ultimele k elemente ale șirului sunt
ordonate și pot fi ignorate la pașii următori.
Exemplu:

Complexitate: O(n2)

public void bubbleSort(int myArray[], int number)


{
int i, j;
for (j=number-1; j>1; j--) // buclă exterioară (înapoi)
{ for (i=0; i<j; i++) // buclă interioară (în față)
{ if( myArray[i] > myArray[i+1] )
{ temp = myArray[i];
myArray[i] = myArray[i+1];
myArray[i+1] = temp;
}
} // sfârșit buclă exterioară for
} // sfârșit buclă exterioară for
} // sfârțit bubbleSort()
5. Quicksort

Quicksort este un algoritm de tipul divide-and-conquer (“desparte și cucerește”).

Algoritmii divide-and-conquer rezolvă problema împărțind-o în mai multe subprobleme.


Acestea sunt rezolvate recursiv, obținându-se soluții la fiecare subproblema. În final,
soluțiile subproblemelor sunt combinate și se obține soluția problemei inițiale.

Pentru a sorta șirul S = {s1, s2, …, sn}, se selectează unul dintre elementele lui S, care
se va numi pivot și se va nota cu p . Elementele rămase din S se vor muta astfel încât se
formează două subșiruri L și G.
• L conține elementele mai mici decât p
• G conține elementele mai mari decât p
L și G sunt subșiruri nesortate.
Recursiv, aplicăm aceeași metodă pe subșirurile L și G.

Algoritm:

1. Alege pivot.
2. Parcurge șirul S de la stânga la dreapta până când este găsit un element
s[i] >=p
3. Parcurge șirul S de la dreapta la stânga până când este găsit un element
s[j] <=p
4. Inversează elementele s[i] și s[j] dacă i<=j.
5. Se repetă pașii 2, 3, 4 până când i>j.
În acest moment șirul este împărțit în două subșiruri.
Se repetă pașii pentru fiecare subșir.
Împărțirea în subșiruri se continuă până când șirul este complet sortat!!!

Complexitatea:

 cel mai bun caz (subșiruri egale): O(n log n)


 cel mai dezavantajos caz: O(n2)

Exemplu:

9 5 8 7 3 12 10

i -> <- j

i=0 => s[i]=9 > 7

j=4 => s[j]=3 < 7

=> s[0] <-> s[4]


3 5 8 7 9 12 10

i+1 =>i=1: s[1]=5 < 7;

i+1 =>i=2: s[2]=8 > 7

j-1 =>j=3: s[3]=7 <= 7

=> s[2] <-> s[3]

3 5 7 8 9 12 10

i+1 => i=3

j-1 => j=2

=>i>j => fără inversare

Vectorul este împărțit în:

3 5 7 8 9 12 10

<= pivot > pivot

… și așa mai departe

6. Sortarea shell

 Algoritmul se bazează pe sortarea prin inserție dar are o performanță mai bună.
 A fost inventat de Donald Shell în 1959.
 Complexitatea este: O(n(log n)2).
 Sortarea se face prin compararea elementelor aflate la o anumită distanță una de
cealaltă. Dacă nu sunt în ordine, ele se inversează. Numărul de poziții dintre ele
trebuie să scadă după fiecare parcurgere a șirului.
 Spațiul dintre elemente se numește distanță și, în general, se alege ca fiind jumătatea
numărului de elemente din șirul ce trebuie sortat.
Exemplu:

Metode de căutare
După aplicarea unei metode de sortare, șirul de elemente este ordonat și se poate efectua mult
mai ușor căutarea unui anumit element.

Tipuri de căutări:

a. Căutare liniară
b. Căutare binară

a. Căutarea liniară se execută în aceeași manieră ca în cazul căutării într-un șir nesortat.
Diferența este că, de data aceasta, șirul fiind sortat, căutarea se oprește atunci când este găsit
un element cu o valoare mai mare decât a elementului căutat.

public static int linearSearch(int[] happy, int Key) {

for (int current = 0; current < happy.length; current++) {


if (happy [current] > key)
return -1;
else if (happy[current] == Key)
return current; // am găsit Key și întorc indexul.
}
return -1; // nu am găsit elementul căutat
}
b. Căutarea binară este mai rapidă decât cea liniară, mai ales în cazul șirurilor de
dimensiuni mari. Mai jos este prezentată metoda de căutare binarySearch() care va găsi
elementul dorit prin împărțirea șirului în două jumătăți așa cum este descris și în figură.

public int binarySearch(double Key)


{
int lowerLimit = 0;
int upperLimit = number-1;
int current; // current index

while(true)
{
current = (lowerLimit + upperLimit ) / 2;
if(happy[current]==Key) // happy este denumirea șirului în care caut
return current; // l-am găsit!
else if(lowerLimit > upperLimit)
return -1; // nu pot să-l găsesc
else // împart șirul
{
if(happy[current] < Key)
lowerLimit = current + 1; // elementul este în jumătatea superioară
else
upperLimit = current - 1; // elementul este în jumătatea inferioară
}
}
} // end find()

Această metodă începe prin a poziționa variabilele lowerLimit și upperLimit în prima și


respectiv ultima poziție a șirului. Ele devin limitele între care elementul Key poate fi găsit.
Apoi, într-o buclă while, indexul curent (numit current) este setat la mijlocul distanței dintre
upperLimit și lowerLimit. Întâi trebuie verificat dacă elementul current este exact cel căutat.
Dacă nu, șirul este împărțit în două.
TEMA

Se consideră o matrice pătratică N x N cu elemente numere întregi. Să se sorteze în ordine


crescătoare de sus în jos fiecare coloană cu indice par folosind algoritmul de sortare prin
inserție și în ordine descrescătoare fiecare coloană cu indice impar, folosind algoritmul de
sortare prin selecție. Apoi să se afișeze matricea rezultată.

Observații!!!

 Programul va fi trimis prin email (nirvana.popescu@cs.pub.ro) până la data limită


05.01.2016 (inclusiv).

 Dacă nu primiți o confirmare din partea mea în 24 de ore, trimiteți fișierul din nou.

 Tema valorează 1 punct din nota finală (după cum s-a anunțat la începutul
semestrului).

 Rezolvările identice sunt penalizate cu 1 punct în minus la nota finală.

You might also like