Sunteți pe pagina 1din 10

Curs 5 - Programarea calculatoarelor i limbaje de programare

Metode de sortare
1. Concepte generale
Sortarea datelor este un pas important care trebuie s fie realizat nainte de aplicarea
altor algoritmi ca, de exemplu, a algoritmului de cutare.
o
Muli cercettori n informatic au petrecut mult timp dezvoltnd diverse metode de
sortare, deoarece aceti algoritmi importani n orice implementare, dar sunt i foarte
mari consumatori de timp.
o

Exemple de sortri:

Sortare prin inserie,


Sortare prin selecie,
Sortare Bubble
Sortare rapid (quicksort)
Sortare shell

2. Sortarea prin inserie


S considerm irul:
S = {s1, s2, , sn}
Format din elemente aparinnd universului U. Scopul sortrii este de a rearanja elementele
din S astfel nct s formm un ir nou S n care elementele sunt n ordine.
ncercm s formm o serie de iruri sortate S0, S1, S2, ,Sn, astfel:
1. Primul ir sortat este mulimea vid S0 : S0 = {}.
2. Avnd irul Si n seria de iruri sortate, urmtorul ir n serie este Si+1, obinut prin
inserarea elementului (i+1) al irului nesortat si+1 n poziia corect n irul Si.
Fiecare ir Si conine primele i elemente ale irului nesortat S.
De aceea, irul final Sn este exact irul sortat pe care l cutam: S = Sn.

Exemplu:

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


{
int initial, sort;
for (sort=1; sort < number; sort++)
// number este numrul 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;
}
} // sfrit 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 stnga atunci cnd temp //este
mai mic dect valoarea curent verificat.
Complexitatea acestui algoritm este: O(n2)
3. Sortarea prin selecie
La fiecare pas, se face o cutare liniar a elementelor nesortate pentru a se determina poziia
celui mai mare element rmas. Acest element este apoi mutat n poziia corect a irului prin
inversarea lui cu elementul ce ocup respectiva poziie.
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;
}
}// sfrit 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 (alturate) sunt comparate i inversate
dac este cazul. nti 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, pn n ultima poziie a acestuia.
n general, dup k treceri prin irul de date, ultimele k elemente ale irului sunt
ordonate i pot fi ignorate la paii urmtori.

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;
}
} // sfrit bucl exterioar for
} // sfrit bucl exterioar for
} // sfrit bubbleSort()

5. Quicksort
Quicksort este un algoritm de tipul divide-and-conquer (desparte i cucerete).
Algoritmii divide-and-conquer rezolv problema mprind-o n mai multe subprobleme.
Acestea sunt rezolvate recursiv, obinndu-se soluii la fiecare subproblema. n final,
soluiile subproblemelor sunt combinate i se obine soluia problemei iniiale.
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 rmase din S se vor muta astfel nct se
formeaz dou subiruri L i G.
L conine elementele mai mici dect p
G conine elementele mai mari dect p
L i G sunt subiruri nesortate.
Recursiv, aplicm aceeai metod pe subirurile L i G.

Algoritm:
1. Alege pivot.
2. Parcurge irul S de la stnga la dreapta pn cnd este gsit un element
s[i] >=p
3. Parcurge irul S de la dreapta la stnga pn cnd este gsit un element
s[j] <=p
4. Inverseaz elementele s[i] i s[j] dac i<=j.
5. Se repet paii 2, 3, 4 pn cnd i>j.
n acest moment irul este mprit n dou subiruri.
Se repet paii pentru fiecare subir.
mprirea n subiruri se continu pn cnd irul este complet sortat!!!
Complexitatea:

cel mai bun caz (subiruri egale): O(n log n)


cel mai dezavantajos caz: O(n2)

Exemplu:
9

i ->

12

10
<- j

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


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

12

10

12

10

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

i+1 => i=3


j-1 => j=2
=>i>j => fr inversare
Vectorul este mprit n:

<= pivot

9
> pivot

i aa mai departe

6. Sortarea shell

Algoritmul se bazeaz pe sortarea prin inserie 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. Numrul de poziii dintre ele
trebuie s scad dup fiecare parcurgere a irului.
Spaiul dintre elemente se numete distan i, n general, se alege ca fiind jumtatea
numrului de elemente din irul ce trebuie sortat.

Exemplu:

Metode de cutare
Dup aplicarea unei metode de sortare, irul de elemente este ordonat i se poate efectua mult
mai uor cutarea unui anumit element.
Tipuri de cutri:
a. Cutare liniar
b. Cutare binar

a. Cutarea liniar se execut n aceeai manier ca n cazul cutrii ntr-un ir nesortat.


Diferena este c, de data aceasta, irul fiind sortat, cutarea se oprete atunci cnd este gsit
un element cu o valoare mai mare dect a elementului cutat.
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 gsit Key i ntorc indexul.
}
return -1;
// nu am gsit elementul cutat
}

b. Cutarea binar este mai rapid dect cea liniar, mai ales n cazul irurilor de
dimensiuni mari. Mai jos este prezentat metoda de cutare binarySearch() care va gsi
elementul dorit prin mprirea irului n dou jumti aa 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 gsit!
else if(lowerLimit > upperLimit)
return -1;
// nu pot s-l gsesc
else
// mpart irul
{
if(happy[current] < Key)
lowerLimit = current + 1; // elementul este n jumtatea superioar
else
upperLimit = current - 1; // elementul este n jumtatea inferioar
}
}
} // end find()

Aceast metod ncepe prin a poziiona variabilele lowerLimit i upperLimit n prima i


respectiv ultima poziie a irului. Ele devin limitele ntre care elementul Key poate fi gsit.
Apoi, ntr-o bucl while, indexul curent (numit current) este setat la mijlocul distanei dintre
upperLimit i lowerLimit. nti trebuie verificat dac elementul current este exact cel cutat.
Dac nu, irul este mprit n dou.

TEMA

Se consider o matrice ptratic N x N cu elemente numere ntregi. S se sorteze n ordine


cresctoare fiecare linie cu indice par i n ordine descresctoare fiecare linie cu indice impar,
folosind algoritmul de sortare prin selecie i apoi s se afieze matricea rezultat.
Observaii!!!
Programul va fi trimis prin email (nirvana.popescu@cs.pub.ro) pn la data limit
05.01.2015 (inclusiv).
Dac nu primii o confirmare din partea mea n 24 de ore, trimitei fiierul din nou.
Tema valoreaz 1 punct din nota final (dup cum s-a anunat la nceputul
semestrului).

Rezolvrile identice sunt penalizate cu 1 punct n minus la nota final.