Documente Academic
Documente Profesional
Documente Cultură
Algoritmi de Sortare
Algoritmi de Sortare
Se dau n numere ntregi, elemente ale unui vector a. Se cere s se aranjeze elementele
vectorului a n ordine cresctoare.
Subalgoritm Selecie(n,a)
1: pentru i=1,n-1 execut:
2: min = a[i]
3: pentru j=i+1,n execut:
4: dac min > a[j] atunci
5:
min = a[j]
6:
k = j Sfd 4: Sfp 3:
7: dac min <> a[i] atunci
8:
aux = a[i]
9:
a[i] = a[k]
10: a[k] = aux Sfd 7: Sfp 1:
Exemplu
Fie tabloul A = (5, 0, 8, 7, 3).
Subalgoritm Selecie(n,a)
1: pentru i=1,n-1 execut:
2: pentru j=i+1,n execut:
3: dac a[i] > a[j] atunci
4:
aux = a[i]
5:
a[i] = a[j]
6:
a[j] = aux sfd 3: sfp 2: sfp 1:
Complexitatea algoritmului: Pentru acest algoritm de sortare nu putem spune c exist caz
favorabil, nefavorabil sau mediu, deoarece numrul de pai efectuai este n(n-1)/2 indiferent de
structura datelor de intrare. Aadar, ordinul de complexitate este (n2). Numrul de comparri este tot
n(n-1)/2, ns pentru cazul n care irul este ordonat cresctor se vor face doar n atribuiri (se execut
doar instruciunea de atribuire 2:)
Figura 2.1 Modul de ordonare a crilor, folosind metoda sortrii prin inserie.
Pseudocodul pentru sortarea prin inserie este prezentat ca o procedur numit Sorteaz-Prin-Inserie,
care are ca parametru un vector A[1..n] coninnd un sir de lungime n care urmeaz a fi sortat. (Pe
parcursul codului, numrul de elemente ale lui A este notat prin lungime[A].) Numerele de intrare sunt
sortate pe loc, n cadrul aceluiai vector A, cel mult un numr constant dintre acestea sunt memorate n
zone de memorie suplimentare. Cnd Sorteaza-Prin-Inserie se termin, vectorul iniial A va conine
elementele irului de ieire sortat.
Subalgoritm Sorteaza-Prin-Inserie(A)
1: pentru j 2, lungime[A] executa
2: cheie A[j]
3: i j - 1
4: ct timp i > 0 i A[i] > cheie executa
5: A[i + 1] A[i]
6: i i 1 sfc 4:
7: A[i + 1] cheie {Insereaza A[j] n sirul sortat A[1..j - 1]} sfp 1:
Figura 2.2 ilustreaz modul de funcionare a acestui algoritm pentru A = (5, 2, 4, 6, 1, 3). Indicele j
corespunde crii care urmeaz a fi inserat n mna stnga. Elementele A[1..j - 1] corespund
mulimii de cri din mna, deja sortate, iar elementele A[j + 1..n] corespund pachetului de cri aflate
nc pe mas. Indicele se deplaseaz de la stnga la dreapta n interiorul vectorului. La fiecare iteraie,
elementul A[j] este ales din vector (linia 2). Apoi, plecnd de la poziia j - 1, elementele sunt, succesiv,
deplasate o poziie spre dreapta pn cnd este gsita poziia corecta pentru A[j] (liniile 36), moment
n care acesta este inserat pe poziia corect n vectorul ordonat (linia 7).
a1
5
2
2
2
1
1
a2
2
5
4
4
2
2
a3
4
4
5
5
4
3
a4
6
6
6
6
5
4
a5
1
1
1
1
6
5
a5
3
3
3
3
3
6
Figura 2.2 Modul de operare a procedurii Sorteaza-Prin-Inserie asupra vectorului A =(5, 2, 4, 6, 1, 3).
Poziia indicelui j este indicat prin colorarea celulei corespunztoare din tabelul din figur.
Complexitatea algoritmului: Sortarea prin inserie are un timp de execuie n cazul cel mai
defavorabil de (n2) (pronunat teta de n ptrat).
Observaia cu privire la faptul c la fiecare parcurgere a ajuns cel puin un element pe locul su definitiv
n irul ordonat poate fi fructificat, deoarece constatm c astfel, la urmtorul pas nu mai sunt
necesare verificrile n care intervine acest element i cele care se afl dup el n ir, acestea fiind deja
sortate cresctor. Rezult c la fiecare parcurgere am putea micora cu 1 numrul elementelor
verificate. Dar este posibil ca la o parcurgere s ajung mai multe elemente n locul lor definitiv.
Rezult c vom ine minte indicele ultimului element care a intervenit n interschimbare i verificrile le
vom efectua doar pn la acest element. Astfel, ajungem la urmtorul subalgoritm mbuntit ca
performan:
a1
a2
Numrul parcurgerii
iniial
4
3
1
3
2
2
2
1
3
1
2
Total interschimbri
a3
a4
2
1
3
3
1
4
4
4
Numrul de interschimbri
3
2
1
6
Astfel, vom spune c metoda bulelor are un timp de execuie n cazul cel mai defavorabil de (n2).
Subalgoritm Numrare(n,A)
1: pentru i=1,n execut
2: k = 0
3: pentru j=1,n execut
4: dac (A[i] > A[j]) atunci
5:
k = k + 1 { numrm cte elemente sunt mai mici dect A[i] }
6:
B[k+1] = A[i] { pe A[i] l punem pe poziia corespunztoare din B } sfd 4: sfp 3:
7: A = B { copiem peste irul A ntreg irul B }
Exemplu
Fie tabloul A cu 4 elemente: 7, 2, 3, 1.
i j Relaia k bk + 1
11 i = j 0
12 7 > 2 1
13 7 > 3 2
1 4 7 > 1 3 b4 = 7
21 2 < 7 0
22 i = j 0
23 2 < 3 0
2 4 2 > 1 1 b2 = 2
31 3 < 7 0
32 3 > 2 1
33 i = j 1
3 4 3 > 1 2 b3 = 3
4 1 1 < 7 0
4 2 1 < 2 0
4 3 1 < 3 0
4 4 i = j 0 b1 = 1
Algoritmul funcioneaz n aceast form dac elementele tabloului A sunt distincte, altfel n
B vor rmne elemente necopiate din A, deoarece dou elemente egale se vor copia n B pe aceeai
poziie. De exemplu, pentru un tabloul A cu 4 elemente: 7, 2, 3, 3 se va obine 2, 3, 0, 7 dac n B am
avut iniial doar elemente nule.
Aceast situaie se poate remedia n 2 moduri:
1. mai parcurgem o dat irul final i toate elementele care nu respect relaia de ordine le modificm
atribuindu-le valoarea din stnga. Astfel, din irul 2, 3, 0, 7 vom obine 2, 3, 3, 7.
Algoritmul modificat este urmtorul:
Subalgoritm Numrare(n,a)
1: pentru i=1,n execut
2: k = 0
3: pentru j=1,n execut
Subalgoritm Numrare(n,a)
1: pentru i=1,n execut
2: k = 0
3: pentru j=1,n execut
4: dac (a[i] > a[j]) i (i <> j) atunci
5: k = k + 1
6: ct timp b[k+1] = a[i] execut {cat timp n B a fost deja pus un element cu aceeasi valoare}
8: k = k + 1
9: b[k+1] = a[i]
10: a = b
Complexitatea algoritmului: Pentru acest algoritm de sortare nu putem spune c exist caz
favorabil, nefavorabil sau mediu, deoarece numrul de pai efectuai este n2 indiferent de structura
datelor de intrare. Aadar, ordinul de complexitate este (n2).
Exemplu
Presupunem c toate valorile din vectorul de sortat sunt numere naturale <=1000.
Vom folosi un vector de frecvene f.
Subalgoritm Ordonare_cu_ir_de_Frecvene(n,a,x,y):
1: x = 0
2: y = 1000
3: pentru i=x,y execut
f[i] = 0 {iniializeaz frecvenele cu 0} sfp 3:
4: pentru i=1,n execut:
f[A[i]] = f[A[i]] + 1 {mrete frecvena fiecrui element din A} sfp 4:
5: k = 0
6: pentru i=x,y execut:
7: pentru j=1,f[i] execut:
8:
k=k+1
9:
A[k] = i {pune napoi n A fiecare element de cte ori este frecvena lui} sfp 7: sfp 6:
Fie irul (2, 1, 1, 0, 2, 3, 0, 2).
Valorile elementelor sunt numere naturale 0,1,2,3. irul de frecvene construit de algoritmul de mai sus
va fi va fi f=(2, 2, 3, 1), f[0]=2, f[1]=2,f[2]=3,f[3]=1.
Corespunztor ultimei secvene din algoritm se vor scrie dou valori 0 consecutive n a, apoi 2 elemente
egal cu 1, urmeaz trei elemente de 2, urmat de o valoare 3: 0, 0, 1, 1, 2, 2, 2, 3.
Dei este un algoritm liniar, eficiena lui trebuie bine studiat nainte de a-l aplica. Eficienta depinde
att de numrul de valori din vectorul iniial, ct i de valorile propriu-zise. Algoritmul depinde liniar de
n, numrul de valori din vector, dar capacitatea de memorie necesar pentru vectorul de frecvene i
apoi numrul de pai ai instruciunii 6: depinde de limitele n care se afl valorile din ir, iar n funcie
de acestea, algoritmul poate deveni mai puin eficient dect unul cu ordin ce complexitate (n2). Un
exemplu n acest caz, dac vrem s ordonm 100 de numere din intervalul [1, 15.000]. O ordonare
(n2) ar face maxim 10000 de pai, iar ordonarea cu frecvene face 15.000, ca s nu mai vorbim de
risipa de memorie care se face n cazul folosirii vectorului de frecvene.
5.2 Sortarea prin numrarea apariiilor i a elementelor mai mici
Acest algoritm poate fi privit ca o variant a algoritmului anterior, obinut prin numrarea i a
elementelor mai mici, nu doar a frecvenei de apariie.
Sortarea prin numrare presupune c fiecare dintre cele n elemente ale datelor de intrare este un
numr ntreg ntre 1 i k, pentru un numr ntreg k oarecare. Cnd k = (n), sortarea se executa n
timpul (n).
Ideea de baza n sortarea prin numrare este de a determina numrul de elemente mai mici dect x,
pentru fiecare element x din datele de intrare. Aceast informaie poate fi utilizat pentru a poziiona
elementul x direct pe poziia sa din tabloul de ieire. De exemplu, dac exist 17 elemente mai mici
dect x, atunci x va fi pe poziia 18 n tabloul de ieire. Aceast schem trebuie uor modificat n
situaia n care exist mai multe elemente avnd aceeai valoare, ntruct nu dorim s le aezm pe
toate n aceeai poziie.
n algoritmul pentru sortarea prin numrare presupunem c datele de intrare formeaz un tablou
A[1..n], i deci lungime [A] = n. Sunt necesare alte doua tablouri suplimentare, tabloul B [1..n], care
cuprinde datele de ieire sortate, i tabloul C [1..k], pentru stocarea temporara n timpul lucrului.
Subalgoritm Sortare-Prin-Numarare(A,B, k)
1: pentru i 1, k execut
2: C [i] 0
3: pentru j 1, lungime [A] execut
4: C [A[j]] C [A[j]] + 1
5: { C[i] conine acum numrul elementelor egale cu i.} sfp 3:
6: pentru i 2, k execut
7: C [i] C [i] + C [i - 1]
8: { C[i] conine numrul elementelor mai mici sau egale cu i.} sfp 6:
9: pentru j lungime [A] , 1,-1 execut
10: B [C [A[j]]] A[j]
11: C [A[j]] C [A[j]] - 1
Algoritmul de sortare prin numrare este ilustrat n figura 5.2.1. Dup iniializarea din liniile12, n
liniile 34 se contorizeaz fiecare element de intrare. Dac valoarea unui element de intrare este i, se
incrementeaz valoarea lui C [i]. Astfel, dup liniile 34, C[i] pstreaz un numr de elemente de
intrare egal cu i pentru fiecare numr ntreg i = 1,2, , k. n liniile 67 se determin, pentru fiecare
i = 1, 2, , k, numrul elementelor de intrare mai mici sau egale dect i, aceasta se realizeaz prin
pstrarea n C[k] a sumei primelor k elemente din tabloul iniial.
n final, n liniile 911, fiecare element A[j] se plaseaz pe poziia sa corect determinat din tabloul de
ieire B, astfel nct acesta este ordonat. Dac toate cele n elemente sunt distincte, la prima execuie a
liniei 9, pentru fiecare A[j], valoarea C[A[j]] este poziia final corect a lui A[j] n tabloul de ieire,
ntruct exist C [A[j]] elemente mai mici sau egale cu A[j]. Deoarece elementele ar putea s nu fie
distincte, decrementm valoarea C[A[j]] de fiecare dat cnd plasm o valoare A[j] n tabloul B,
aceasta face ca urmtorul element de intrare cu o valoare egal cu A[j], dac exist vreunul, s mearg
n poziia imediat dinaintea lui A[j] n tabloul de ieire.
Ct timp necesita sortarea prin numrare? Bucla pentru din liniile 12 necesit timpul (k), bucla
pentru din liniile 34 necesit timpul (n), bucla pentru din liniile 67 necesit timpul (k), iar bucla
pentru din liniile 911 necesit timpul (n). Deci timpul total este (k + n). n practic se utilizeaz
sortarea prin numrare cnd avem k = (n), caz n care timpul necesar este (n).
O proprietate important a sortrii prin numrare este stabilitatea: numerele cu aceeai valoare apar n
tabloul de ieire n aceeai ordine n care se gsesc n tabloul de intrare. Adic, legturile dintre dou
numere sunt distruse de regula conform creia oricare numr care apare primul n vectorul de intrare,
va aprea primul i n vectorul de ieire. Desigur, stabilitatea este importanta numai cnd datele
nvecinate sunt deplasate mpreuna cu elementul n curs de sortare.