Documente Academic
Documente Profesional
Documente Cultură
iLeft:= iLeft+1;
endwhile
(2b) while A[iRight] > x do
iRight:= iRight - 1;
endwhile
(3) if iLeft <= iRight then
Interschimb(A[iLeft], A[iRight]);
iLeft:= iLeft+1;
iRight:= iRight-1;
endif
until (iLeft > iRight)
endproc{Partition}
(3)
(2a)
1
i-1 i
valori < x
(2b)
j j-1
valori > x
procedure QuickSortIter1(A);
Push(Stack, 1, n);
repeat
Pop(Stack, Left, Right);
repeat
{noul ciclu repetitiv n care se aplic partiia pe A[Left..Right]}
Partition(Left, Right, i, j);
{introducem n stiva Stack intervalele din dreapta}
if i < Right then
Push(Stack, i, Right);
endif
{redefinim extrema dreapt a intervalului din stnga care este reluat la
prelucrare iterativ}
Right := j;
until Left >= Right
until Stack =
endproc {QuickSortIter1}
O alt alegere a pivotului pentru sortarea rapid.
Pn acum am ales ca pivot valoarea median din vectorul pe care facem partiia. Ce
se ntmpl dac alegem o valoare situat la una dintre extremiti?
S presupunem c, pentru partiionarea vectorului A[Left..Right] alegem x=A[Left].
Atunci pasul (2a) din algoritmul de partiionare (parcurgerea de la stnga la dreapta a
vectorului pn la primul indice i pentru care A[i] x) nu mai are sens, cci acest indice
este chiar Left. Executm (2b), adic parcurgem de la dreapta la stnga vectorul pn la
primul indice j pentru care A[j] x.
Pasul (3) devine: dac Left < j, atunci interschimb A[Left] cu A[j].
Observm c valoarea pivot x = A[Left] a participat la interschimbare, i se afl acum
plasat n extremitatea dreapt a subvectorului A[Left..j]. Relum acum parcurgerea de
tip (2a) de la stnga la dreapta. Parcurgerea de tip (2b) nu mai are sens. La sfrit
interschimbm. Observm c valoarea pivot particip din nou la interschimbare.
Procedeul continu pn cnd cele dou parcurgeri se ntlnesc, adic atta timp ct mai
exist componente n vector care nu au fost comparate cu pivotul. La sfrit obinem
valoarea pivot x plasat la locul ei final n vector. Fie loc indicele lui A ce va conine pe x.
Avem atunci:
A[k] x pentru orice k [1..loc-1]
A[k] x pentru orice k [loc+1..n]
deci subintervalele ce trebuie procesate n continuare sunt A[1..loc-1] i A[loc+1..n].
Dm mai jos noua procedur de partiionare. La parcurgeri ea va lsa pe loc valorile
egale cu pivotul. Indicele loc ine minte tot timpul componenta pe care se afl valoarea
pivot, iar la sfrit o transmite procedurii apelante pentru a putea fi calculate noile capete
ale subvectorilor rezultai.
procedure Partition2 (Left, Right: indice, var loc:indice)
Dac fiecare partiionare njumtete intervalul pe care se aplic (cazul cel mai
favorabil), atunci vom avea un numr total de log2n subintervale de procesat, deci
numrul total de comparaii este de ordinul lui O(nlog2n). Tot aceasta este performana i
n cazul mediu.
Putem avea i cazul cel mai nefavorabil, cnd fiecare pivot ales x este maximul
sau minimul din subinterval. Atunci, la fiecare partiionare se genereaz un subinterval de
lungime 1 i altul de lungime n-1, deci avem un numr total de n intervale de prelucrat.
Numrul total de comparaii va fi n acest caz de ordinul lui O(n2), exact ca i
performana algoritmilor direci.
O alt caracteristic a acestui algoritm este faptul c necesit spaiu n plus pentru
meninerea subintervalelor. Att versiunile iterative, care gestioneaz explicit stiva ce
menine intervalele, ct i cele recursive, au nevoie de acest spaiu suplimentar.
Aplicaie a procedurii de partiionare la gsirea medianei.
Mediana unui vector este acea valoare dintre componentele sale care este mai mare
dect jumtate dintre componente i mai mic dect cealalt jumtate. Dac am sorta nti
vectorul, atunci mediana s-ar gsi la mijlocul vectorului. Vrem s gsim ns aceast
valoare fr a sorta ntregul vector.
Problema se generalizeaz la gsirea valorii a k-a dintr-un vector, cea care este
mai mare dect k-1 componente i mai mic dect n-k componente, pe scurt, cea care ar
ocupa locaia A[k] n vectorul sortat, fr a sorta ntregul vector.
C. A. R. Hoare a propus un algoritm care se bazeaz pe procedura de partiionare
a sortrii rapide. Se aplic procedura de partiionare pe ntregul vector, deci Left=1 i
Right=n, cu valoarea pivot x = A[k]. Indicii i i j cu care se termin partiia au
proprietile:
i > j (cele dou parcurgeri s-au ntlnit)
A[s] x, pentru orice s < i
A[s] x, pentru orice s > j .
Avem trei cazuri posibile pentru indicele k n raport cu indicii i i j:
(1) j < i < k
k Right
Left j i
Limita unde se termin cele dou partiii este n stnga lui k (din cauz c valoarea pivot x a fost
mai mic dect valoarea cutat). Se reia partiionarea pe subvectorul A[i..Right].
(2) k < j < i
Left
Right
j i
Cazul simetric lui (1). Limita unde se termin partiiile
este n dreapta lui k. Se reia partiionarea pe subvectorul
A[Left..j].
Left
j ki
Right
Exerciii.
6.10
6.11
6.12
6.13
6.14
6.15
6.16
6.17
6.18