Sunteți pe pagina 1din 5

Heapsort

Prin algoritmul heapsort se ordoneaz elementele n spaiul alocat vectorului: la un moment


dat doar un numr constant de elemente ale vectorului sunt pstrate n afara spaiului alocat
vectorului de intrare. Astfel, algoritmul heapsort combin calitile a dou tipuri de algoritmi
de sortare, sortare intern i sortare extern.
Heapsort introduce o tehnica nou de proiectare a algoritmilor bazat pe utilizarea unei
structuri de date, numit de regula heap. Structura de date heap este util nu doar pentru
algoritmul heapsort, ea poate fi la fel de util i n tratarea eficient a unei cozi de prioritate.
Termenul heap a fost introdus i utilizat iniial n contextul algoritmului heapsort, dar acesta se
folosete i n legtur cu alocarea dinamic, respectiv n tratarea memoriei bazate pe
colectarea reziduurilor (garbage collected storage), de exemplu n limbajele de tip Lisp.
Structura de date heap nu se refera la heap-ul menionat n alocarea dinamica, i ori de cte
ori, n aceasta lucrare voi vorbi despre heap, vom nelege structura definit aici pentru
heapsort.
Structura de date heap (binar) este un vector care poate fi vizualizat sub forma unui arbore
binar aproape complet, conform figurii 1.8. Fiecare nod al arborelui corespunde unui element al
vectorului care conine valorile ataate nodurilor. Arborele este plin, exceptnd eventual nivelul
inferior, care este plin de la stnga la dreapta doar pn la un anumit loc. Un vector A care
reprezint un heap are doua atribute: lungime[A], reprezint numrul elementelor din vector i
dimensiune-heap[A] reprezint numrul elementelor heap-ului memorat n vectorul A. Astfel,
chiar daca A[1..lungime[A]] conine n fiecare element al sau date valide, este posibil ca
elementele urmtoare elementului A[dimensiune-heap[A]], unde dimensiune- heap[A]
lungime[A], s nu aparin heap-ului. Rdcina arborelui este A[1]. Dat fiind un indice i,
corespunztor unui nod, se pot determina uor indicii printelui acestuia Parinte(i), al fiului
Stnga(i) i al fiului Dreapta(i).
Parinte(i)
returneaza [i/2]
Stnga(i)
returneaza 2i
Dreapta(i)
returneaza 2i + 1

Figura 1.8 Un heap reprezentat sub forma unui arbore binar (a) i sub forma unui vector (b).
Numerele nscrise n cercurile reprezentnd nodurile arborelui sunt valorile ataate nodurilor,
iar cele scrise lng cercuri sunt indicii elementelor corespunztoare din vector.
n cele mai multe cazuri, procedura Stnga poate calcula valoarea 2i cu o singura instruciune,

translatnd reprezentarea binara a lui i la stnga cu o poziie binara. Similar, procedura


Dreapta poate determina rapid valoarea 2i + 1, translatnd reprezentarea binara a lui i la
stnga cu o poziie binara, iar bitul nou intrat pe poziia binara cea mai nesemnificativa va fi 1.
n procedura Parinte valoarea [i/2]se va calcula prin translatarea cu o poziie binara la dreapta
a reprezentrii binare a lui i. ntr-o implementare eficienta a algoritmului heapsort, aceste
proceduri sunt adeseori codificate sub forma unor macro-uri sau a unor proceduri n-line.
Pentru orice nod i, diferit de rdcina, este adevrat urmtoarea proprietate de heap:
A[Parinte(i)] A[i]
adic valoarea ataata nodului este mai mic sau egal cu valoarea asociat printelui su.
Astfel cel mai mare element din heap este pstrat n rdcin, iar valorile nodurilor oricrui
subarbore al unui nod sunt mai mici sau egale cu valoarea nodului respectiv.
Definim nlimea unui nod al arborelui ca fiind numrul muchiilor aparinnd celui mai lung
drum care leag nodul respectiv cu o frunz, iar nlimea arborelui ca fiind nlimea rdcinii.
Deoarece un heap avnd nelemente corespunde unui arbore binar complet, nlimea acestuia
este (log2 n). Vom vedea c timpul de execuie al operaiilor de baz, care se efectueaz pe
un heap, este proporional cu nlimea arborelui i este (log2 n). n cele ce urmeaz, vom
prezenta trei proceduri i modul lor de utilizare n algoritmul de sortare, respectiv ntr-o
structura de tip coada de prioritate.

Procedura Reconstituie-Heap are timpul de execuie (log2 n) i este de prima


importana n ntreinerea proprietii de heap.

Procedura Construieste-Heap are un timp de execuie liniar i genereaz un heap dintrun vector neordonat, furnizat la intrare.

Procedura Heapsort se executa n timpul O(n log2 n) i ordoneaz un vector n spaiul


alocat acestuia.
Procedura Reconstituie-Heap este un subprogram important n prelucrarea heap-urilor.
Datele de intrare ale acesteia sunt un vector A i un indice i din vector. Atunci cnd se apeleaz
Reconstituie-Heap, se presupune c subarborii, avnd ca rdcini nodurile Stnga(i) respectiv
Dreapta(i), sunt heap-uri. Dar, cum elementul A[i] poate fi mai mic dect descendenii si,
acesta nu respecta proprietatea de heap. Sarcina procedurii Reconstituie-Heap este de a
scufunda n heap valoarea A[i], astfel nct subarborele care are n rdcina valoarea
elementului de indice i, s devina un heap.
Subalgoritm Reconstituie-Heap(A, i)
1: l Stnga(i)
2: r Dreapta(i)
3: daca l dimesiune-heap[A] i A[l] > A[i] atunci
4:
maxim l
5: altfel
6:
maxim i
7: daca r dimesiune-heap[A] i A[r] > A[maxim] atunci
8:
maxim r
9: daca maxim <> i atunci
10:
schimba A[i] A[maxim]
11:
Reconstituie-Heap(A, maxim)Figura 1.9 ilustreaz efectul procedurii Reconstituie-Heap.
La fiecare pas se determina cel mai mare element dintre A[i], A[Stnga(i)] i A[Dreapta(i)], iar
indicele sau se pstreaz n variabila maxim. Daca A[i] este cel mai mare, atunci subarborele
avnd ca rdcin nodul i este un heap i procedura se termina. n caz contrar, cel mai mare
element este unul dintre cei doi descendeni i A[i] este interschimbat cu A[maxim]. Astfel,
nodul i i descendenii si satisfac proprietatea de heap. Nodul maxim are acum valoarea
iniiala a lui A[i], deci este posibil ca subarborele de rdcin maxim s nu ndeplineasc
proprietatea de heap. Rezulta c procedura Reconstituie-Heap trebuie apelata recursiv din nou

pentru acest subarbore.


Timpul de execuie al procedurii Reconstituie-Heap, corespunztor unui arbore de rdcin i i
dimensiune n, este (1), timp n care se pot analiza relaiile dintre A[i], A[Stnga(i)] i
A[Dreapta(i)] la care trebuie adugat timpul n care Reconstituie-Heap se executa pentru
subarborele avnd ca rdcin unul dintre descendenii lui i. Dimensiunea acestor subarbori
este de cel mult 2n/3 cazul cel mai defavorabil fiind acela n care nivelul inferior al arborelui
este plin exact pe jumtate astfel, timpul de execuie al procedurii Reconstituie-Heap poate fi
descris prin urmtoarea inegalitate recursiva:
T(n) T(2n/3) + (1):
Timpul de execuie al procedurii Reconstituie-Heap pentru un nod de nlime h poate fi
exprimat alternativ ca fiind egal cu (h).

Figura 1.9 Efectul procedurii Reconstituie-Heap(A, 2), unde dimesiune-heap[A] = 10. (a)
Configuraia iniiala a heap-ului, unde A[2] (pentru nodul i = 2), nu respecta proprietatea de
heap deoarece nu este mai mare dect descendenii si. Proprietatea de heap este restabilita
pentru nodul 2 n (b) prin interschimbarea lui A[2] cu A[4], ceea ce anuleaz proprietatea de
heap pentru nodul 4. Apelul recursiv al procedurii Reconstituie-Heap(A, 4) poziioneaz
valoarea lui i pe 4. Dupa interschimbarea lui A[4] cu A[9], aa cum se vede n (c), nodul 4
ajunge la locul sau i apelul recursiv Reconstituie-Heap(A, 9) nu mai gsete elemente care nu
ndeplinesc proprietatea de heap.
Construirea unui heap
Procedura Reconstituie-Heap poate fi utilizata de jos n sus pentru transformarea vectorului
A[1..n] n heap, unde n = lungime[A]. Deoarece toate elementele subirului A[([n/2]+1)..n]
sunt frunze, acestea pot fi considerate ca fiind heap-uri formate din cte un element. Astfel,
procedura Construieste-Heap trebuie s traverseze doar restul elementelor i s execute
procedura Reconstituie-Heap pentru fiecare nod ntlnit. Ordinea de prelucrare a nodurilor
asigura c subarborii, avnd ca rdcin descendeni ai nodului i s formeze heap-uri nainte

ca Reconstituie-Heap s fie executat pentru aceste noduri.


Subalgoritm Construieste-Heap(A)
1: dimesiune-heap[A] lungime[A]
2: pentru i [lungime[A]/2],1 executa
3:
Reconstituie-Heap(A, i)
Figura 1.10 ilustreaz modul de funcionare al procedurii Construieste-Heap.

Algoritmul heapsort

Algoritmul heapsort ncepe cu apelul procedurii Construieste-Heap n scopul transformrii vectorului de


intrare A[1..n] n heap, unde n = lungime[A]. Deoarece cel mai mare element al vectorului este ataat
nodului rdcinA[1], acesta va ocupa locul definitiv n vectorul ordonat prin interschimbarea sa cu
A[n]. n continuare, excluznd din heap cel de-al n-lea element (i micornd cu 1 dimesiuneheap[A]), restul de A[1..(n - 1)] elemente se pot transforma uor n heap, deoarece subarborii nodului
rdcin au proprietatea de heap, cu eventuala excepie a elementului ajuns n nodul rdcin.

SubalgoritmHeapsort(A)
1: Construieste-Heap(A)
2: pentru i lungime[A], 2 executa
3:
schimba A[1] A[i]
4:
dimesiune-heap[A] dimesiune-heap[A] - 1
5:
Reconstituie-Heap(A, 1)
Apelnd procedura Reconstituie-Heap(A, 1) se restabilete proprietatea de heap pentru vectorul
A[1..(n - 1)]. Acest procedeu se repeta micornd dimensiunea heap-ului de la n - 1 pn la 2.
Figura 1.11 ilustreaz, pe un exemplu, modul de funcionare a procedurii Heapsort, dupa ce n
prealabil datele au fost transformate n heap. Fiecare heap reprezint starea iniiala la nceputul
pasului iterativ (linia 2 din ciclul pentru).
Timpul de execuie al procedurii Heapsort este (n log2 n), deoarece procedura Construieste-Heap se
executa ntr-un timp (n), iar procedura Reconstituie-Heap, apelata de n-1 ori, se executa n timpul
(log2 n).

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