Documente Academic
Documente Profesional
Documente Cultură
Sortarea HEAP PDF
Sortarea HEAP PDF
Contents
1. Heap-uri ............................................................................................................................................ 1
2. Reconstituirea proprietații de heap .................................................................................................. 3
3. Construirea unui heap....................................................................................................................... 6
4. Algoritmul heapsort .......................................................................................................................... 9
5. Cozi de prioritați.............................................................................................................................. 11
Timpul de execuție al agoritmului heapsort este O(n lg n), asemănător sortării prin
interclasare. Heapsort ordonează elementele în spațiul alocat vectorului, asemănător sortării prin
inserție: la un moment dat doar un număr constant de elemente ale vectorului sunt păstrate în
afara spațiului alocat vectorului de intrare. Astfel, algoritmul heapsort combină calitațile celor
doi algoritmi de sortare menționați mai sus.
Heapsort introduce o tehnică nouă de proiectare a algoritmilor bazată pe utilizarea unei
structuri de date. 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 inițial în contextul algoritmului heapsort, dar acesta se foloseste și în legatură cu alocarea
dinamică.
1. Heap-uri
Structura de date heap (binar) este un vector care poate fi vizualizat sub forma unui
arbore binar aproape complet, conform figurii 1. Fiecare nod al arborelui corespunde unui
element al vectorului care conține valorile atasate nodurilor. Arborele este plin, exceptând
eventual nivelul inferior, care este plin de la stânga la dreapta doar pâna la un anumit loc. Un
vector A care reprezintă un heap are două atribute: lungime[A], reprezintă numărul elementelor
din vector și dimensiune-heap[A] reprezintă numărul elementelor heap-ului memorat în vectorul
A. Astfel, chiar dacă A[1..lungime[A]] conține în fiecare element al său date valide, este posibil
Pag 1 din 12
ca elementele urmatoare elementului A[dimensiune-heap[A]], unde dimensiune-heap[A] ≤
lungime[A], să nu aparțină heap-ului. Radacina arborelui este A[1]. Dat fiind un indice i,
corespunzator unui nod, se pot determina ușor indicii părintelui acestuia Parinte(i), al fiului
Stânga(i) și al fiului Dreapta(i).
Parinte(i)
returneaza [i/2]
Stânga(i)
returneaza 2i
Dreapta(i)
returneaza 2i + 1
1
16
2 3
14 10
4 5 6 7
8 7 9 3
8 9 10
2 4 1
Figura 1. a)
1 2 3 4 5 6 7 8 9 10
16 14 10 8 7 9 3 2 4 1
Figura 1. b)
Figura 1. Un heap reprezentat sub forma unui arbore binar (a) și sub forma unui vector (b)
Pag 2 din 12
binare a lui i. Într-o implementare eficientă a algoritmului heapsort, aceste proceduri sunt
adeseori codificate sub forma unor “macro-uri” sau a unor proceduri “in-line”.
Pentru orice nod i, diferit de rădăcină, este adevarată urmatoarea proprietate de heap:
A[Parinte(i)] ≥A[i], (1)
adică valoarea atașată nodului este mai mică sau egală cu valoarea asociată părintelui său. Astfel
cel mai mare element din heap este păstrat în rădăcină, iar valorile nodurilor oricărui subarbore al
unui nod sunt mai mici sau egale cu valoarea nodului respectiv.
Definim înalțimea unui nod al arborelui ca fiind numărul muchiilor aparținând celui mai
lung drum care leagă nodul respectiv cu o frunză, iar înălțimea arborelui ca fiind înălțimea
rădăcinii. Deoarece un heap cu n elemente corespunde unui arbore binar complet, înălțimea
acestuia este Θ(lg n). Timpul de execuție al operațiilor de bază, care se efectuează pe un heap,
este proporțional cu înălțimea arborelui și este O(lg n). În cele ce urmează, sunt prezentate cinci
proceduri și modul lor de utilizare în algoritmul de sortare, respectiv într-o structură de tip coadă
de prioritate.
Procedura Reconstituie-Heap are timpul de execuție O(lg n) și este de primă importanță
în întreținerea proprietații de heap (1);
Procedura Construieste-Heap are un timp de execuție liniar și generează un heap dintr-un
vector neordonat, furnizat la intrare;
Procedura Heapsort se execută în timpul O(n lg n) și ordonează un vector în spațiul
alocat acestuia;
Procedurile Extrage-Max și Insereaza se execută în timpul O(lg n), iar cu ajutorul lor se
poate utiliza un heap în realizarea unei cozi de prioritate.
Pag 3 din 12
dacă l ≤ dimesiune-heap[A] și A[l] > A[i] atunci
maxim ← l
altfel
maxim ← i
dacă r ≤ dimesiune-heap[A] și A[r] > A[maxim] atunci
maxim ← r
dacă maxim ≠ i atunci
schimbă A[i] ↔ A[maxim]
Reconstituie-Heap(A, maxim)
1
16
2 3
i 4 10
4 5 6 7
14 7 9 3
8 9 10
2 8 1
Figura 2. a)
Pag 4 din 12
1
16
2 3
14 10
4 5 6 7
i 4 7 9 3
8 9 10
2 8 1
Figura 2. b)
1
16
2 3
14 10
4 5 6 7
8 7 9 3
8 9 10
2 4 1
Figura 2. c)
Pag 5 din 12
Soluția acestei recurențe se obține pe baza celui de-al doilea caz al teoremei master: T(n)
= O(lg n). Timpul de execuție al procedurii Reconstituie-Heap pentru un nod de înalțime h poate
fi exprimat alternativ ca fiind egal cu O(h).
Construieste-Heap(A)
dimesiune-heap[A] ← lungime[A]
pentru i ← [lungime[A]/2],1 execută
Reconstituie-Heap(A, i)
1 2 3 4 5 6 7 8 9 10
A 4 1 3 2 16 9 10 14 8 7
1
4
2 3
1 3
4 5 6 7
2 i 16 9 10
8 9 10
14 8 7
Pag 6 din 12
Figura 3. a)
1
4
2 3
1 3
4 5 6 7
i 2 16 9 10
8 9 10
14 8 7
Figura 3. b)
1
4
2 3
1 3 i
4 5 6 7
14 16 9 10
8 9 10
2 8 7
Figura 3. c)
1
4
2 3
i 1 10
4 5 6 7
14 16 9 3
8 9 10
2 8 7
Figura 3. d)
Pag 7 din 12
1
i 4
2 3
16 10
4 5 6 7
14 7 9 3
8 9 10
2 8 1
Figura 3. e)
1
16
2 3
14 10
4 5 6 7
8 7 9 3
8 9 10
2 4 1
Figura 3. f)
Pag 8 din 12
Astfel, timpul de execuµie al procedurii Construieste-Heap poate fi estimat ca fiind:
, 〖 -〗
. ∑ / . ∑ / ( ) (4)
De aici rezultă că se poate construi un heap dintr-un vector într-un timp liniar.
4. Algoritmul heapsort
Heapsort(A)
Construieste-Heap(A)
pentru i ← lungime[A], 2 execută
schimbă A[1] ↔ A[i]
dimesiune-heap[A] ← dimesiune-heap[A] - 1
Reconstituie-Heap(A,1)
16 14
14 10 8 10
8 7 9 3 4 7 9 3
2 4 1 2 1 16 i
Figura 4. a) Figura 4. b)
Pag 9 din 12
10 9
8 9 8 3
4 7 1 3 4 7 1 2
i i
2 14 16 10 14 16
Figura 4. c) Figura 4. d)
8 7
7 3 4 3
4 2 1 i 9 1 2 8 i 9
10 14 16 10 14 16
Figura 4. e) Figura 4. f)
4 3
2 3 2 1
1 7 i 8 9 4 i 7 8 9
10 14 16 10 14 16
Figura 4. g) Figura 4. h)
2 1
1 3 i 2 i 3
4 7 8 9 4 7 8 9
10 14 16 10 14 16
Figura 4. i) Figura 4. j)
1 2 3 4 5 6 7 8 9 10
A 1 2 3 4 7 8 9 10 14 16
Figura 4. Modul de funcționare a algoritmului Heapsort. (a) Structura de date heap, imediat după
construirea sa de către procedura Construieste-Heap. (b)-(j) Heap-ul, imediat după câte un apel
al
procedurii Reconstituie-Heap (linia 5 în algoritm). Figura reprezintă valoarea curenta a variabilei
i. Din heap fac parte doar nodurile din cercurile nehașurate. (k) Vectorul A ordonat, obținut ca
rezultat.
Pag 10 din 12
5. Cozi de prioritați
Extrage-Max-Din-Heap(A)
dacă dimesiune-heap[A] < 1 atunci
eroare “depășire inferioară heap”
max ←A[1]
A[1] ← A[dimesiune-heap[A]]
dimesiune-heap[A] ← dimesiune-heap[A] - 1
Reconstituie-Heap(A,1)
returnează maxim
Pag 11 din 12
Procedura Insereaza-În-Heap inserează un nod în heap-ul A. La prima expandare a heap-
ului se adaugă o frunză arborelui. Apoi, se traversează un drum pornind de la această frunză către
rădăcină, în scopul găsirii locului definitiv al noului element.
Insereaza-În-Heap(A,cheie)
dimesiune-heap[A] ← dimesiune-heap[A] + 1
i ←dimesiune-heap[A]
cât timp i > 1 și A[Parinte(i)] < cheie execută
A[i] ←A[Parinte(i)]
i ←Parinte(i)
A[i] ← cheie
16 16
14 10 14 10
8 7 9 3 8 7 9 3
2 4 1 2 4 1
Figura 5. a) Figura 5. b)
16 16
10 15 10
8 14 9 3 8 14 9 3
2 4 1 7 2 4 1 7
Figura 5. c) Figura 5. d)
Figura 5. Operația Insereaza-În-Heap. (a) Heap-ul din figura 4(a) înainte de inserarea nodului
având cheia 15. (b) Se adaugă arborelui o frunză nouă. (c) Se “scufundă” valorile de pe drumul
dintre frunză și rădăcină până la găsirea nodului corespunzator cheii 15. (d) Se inserează cheia
15.
Pag 12 din 12