ALGORYTMY I STRUKTURY DANYCH
WYKŁAD 10 Kopiec Grażyna Mirkowska
PJWSTK, semestr zimowy 2002
Plan wykładu
Kopiec (sterta)
– Definicja
– Operacja wkładanie elementu do kopca – Usuwanie elementu minimalnego
– Koszty operacji
Zastosowanie - algorytm Heap_sort
Implementacja kopca w tablicy
– Konstrukcja kopca w tablicy – Przykład
– Koszt konstrukcji kopca
Kopiec czyli sterta, czyli heap
Kopcem nazywamy etykietowane, doskonałe drzewo binarne częściowo uporządkowane.
Etykietowane drzewo binarne D = <V, E, et> jest kopcem wtedy i tylko wtedy, gdy
(1) D jest drzewem częściowo uporządkowanym:
et(v) < et(v.lewy) i et(v)< et(v.prawy) dla wszystkich wierzchołków v V,
(2) D jest drzewem doskonałym:
wszystkie poziomy drzewa, z wyjątkiem co najwyżej ostatniego poziomu, są maksymalnie zapełnione, a na ostatnim poziomie wszystkie liście są zgrupowane maksymalnie na lewo.
Przykład kopca
1 2 5
4 3 7 8
9 10
To nie jest kopiec , bo nie jest to drzewo
doskonałe(chociaż jest to drzewo cz. uporządkowane)
1 4 7
2 3 5 8
9 10
To nie jest kopiec , bo nie jest to drzewo częściowo uporządkowane (chociaż jest to drzewo doskonałe)
1 2 5
4 3 7 8
9 10 6
Kopiec
Własności:
1.
Etykiety na dowolnej drodze od korzenia do liścia tworzą ciąg uporządkowany rosnąco.2. Element najmniejszy wśród etykiet wierzchołków
znajduje się w korzeniu drzewa.
Wstawianie elementu
Insert : Heap
Insert : Heap Et Et Heap Heap
(1) Dowiązać nowy wierzchołek x do pierwszego z lewej wierzchołka na przedostatnim poziomie drzewa, którego rząd jest <2.
(2) Nadać nowemu wierzchołkowi etykietę e.
(3) Jeżeli tak otrzymane drzewo nie jest częściowo uporządkowane, to przechodząc wzdłuż drogi od liścia x do korzenia, poprawić etykiety zamieniając etykietę ojca z etykietą syna, jeśli etykieta ojca jest większa niż etykieta syna.
Zadanie: Do zbioru etykiet danego kopca D dołączyć nową etykietę e, czyli wykonać operację insert(D,e)
Przykład - dołączanie nowego elementu
1 2 5
4 3 7 8
9 10 6
Po dołączeniu
nowego wierzchołka
0
1 2 5
4 3 7 8
9 10 6 0
Zero „wędruje” wzdłuż drogi do korzenia
3 02
01
0
Usuwanie minimum
delmin : Heap delmin : Heap Heap Heap
Niech e będzie etykietą liścia x znajdującego się najbardziej na prawo na ostatnim poziomie
kopca.
(1) Usunąć wierzchołek x z drzewa d.
(2) Zastąpić etykietę w korzeniu drzewa przez e.
(3) Jeśli tak otrzymane drzewo nie jest kopcem, to zaczynając od korzenia i idąc w kierunku liścia, zamieniać etykietę ojca z etykietą tego z jego synów, którego etykieta ma mniejszą
wartość, tak długo aż zostanie otrzymane drzewo częściowo uporządkowane.
Przykład - usuwanie minimum
0
1 5
4 3 10 8
9 7 6 20 12
12
12
1
12 3
12 6
Usuwamy najmniejszy element zbioru.
pokaz
pokaz
Koszt operacji
h-1 h
n - wierzchołków
Stąd 2 h -1 < n 2 h+1 -1 Czyli 2 h < n +1 2 h+1
h
i h i
i
i n
0 1
0
2 2
Mamy
lg(n+1)-1 h < lg (n+1) Ostatecznie h= lg(n+1)
Wniosek Wniosek
Koszt operacji insert i Koszt operacji insert i delmin wynosi
delmin wynosi O
O( ( lg(n+1) lg(n+1) ). ).
Zastosowanie
(1) Z danego n elementowego zbioru utworzyć kopiec.
(2) Dopóki kopiec nie jest pusty, wypisywać i usuwać element
minimalny kopca.
Algorytm Heap_sort Algorytm Heap_sort
Koszt sortowania = koszt utworzenia kopca + n * O(lg n)
O ile wkładamy kolejno
elementy stosując
operacje insert : O(n lg n)
= O(n lg n)
Implementacja kopca w tablicy
Reprezentujemy kopiec jako parę Tab + idx
Organizacja elementów w tablicy:
Organizacja elementów w tablicy:
Tab[1] = etykieta korzenia
Tab[2i] = etykieta lewego syna wierzchołka i-tego o ile 2i idx
Tab[2i+1] = etykieta prawego syna wierzchołka i-tego o ile 2i+1 idx
tablica etykiet
aktualna liczba elementów w tablicy
Przykład
1 2 5
4 3 7 8
9 10 6
Kopiec Tab: 1 2 5 4 3 7 8 9 10 6 n : 10
1 2 3 4 5 6 7 8 9 10
Reprezentacja
Reprezentacja
tablicowa kopca
tablicowa kopca
Operacja insert w implementacji tablicowej
Kopiec D
5 7 12
10 8 14 19
16 9 11 20
5 7 12 10 8 14 19 16 9 11 20
1 2 3 4 5 6 7 8 9 10 11
Tab:
Insert(D,3)
5 7 12 10 8 14 19 16 9 11 20
1 2 3 4 5 6 7 8 9 10 11
Tab:
3123 7 5 10 8 12 19 16 9 11 20
1 2 3 4 5 6 7 8 9 10 11
Tab:
14123 14
3 12
35 3
Delmin w implementacji tablicowej
3 7 5 10 8 12 19 16 9 11 20
1 2 3 4 5 6 7 8 9 10 11
Tab:
14123 7 5
10 8 12 19
16 9 11 20 14
Delmin(D)
14 7 5 10 8 12 19 16 9 11 20
1 2 3 4 5 6 7 8 9 10 11
Tab:
Ostatecznie :
5 7 12 10 8 14 19 16 9 11 201 2 3 4 5 6 7 8 9 10 11
Tab:
14
14 5
14 12
Konstrukcja kopca w tablicy
Założenie: Znamy z góry liczbę elementów tworzonego kopca.
A B
i
2i 2i+1
1.Tworzymy tablice zawierającą wszystkie elementy.
2.Jeżeli są już utworzone kopce A i B o korzeniach w 2itej i 2i+1szej pozycji, to - albo tab[i] <tab[2i] oraz tab[i]<tab[2i+1] i wtedy mamy już kopiec o korzeniu w i,
- albo tak nie jest i wtedy poprawiamy
ścieżkę „w dół” tak jak w algorytmie delmin.
Algorytm tworzenia kopca
For i:= n div 2 downto 1 do downheap(i) od;
Procedure downheap (k:integer);
/* utwórz kopiec o korzeniu w pozycji k zakładając, że 2k i 2k+1 są korzeniami kopców w tablicy*/
begin
v := tab[k];
while (k<= n div 2 ) do j := 2*k;
if (j<n) then if (tab[j] > tab[j+1] )then j := j+1 fi fi;
if v<tab[j] then exit fi;
tab[k] := tab[j];
k := j;
od;
tab[k] := v;
end;
Przykład - konstrukcja kopca
5 7 1
6 2 8 4
3 9
5 7 1 6 2 8 4 3 9 Tab:
1 2 3 4 5 6 7 8 9
To są liście
5 7 1 6 2 8 4 3 9 Tab:
1 2 3 4 5 6 7 8 9
5 7 1 3 2 8 4 6 9 Tab:
1 2 3 4 5 6 7 8 9
5 7 1 3 2 8 4 6 9 Tab:
1 2 3 4 5 6 7 8 9
5 2 1 3 7 8 4 6 9 Tab:
1 2 3 4 5 6 7 8 9
1 2 5 3 7 8 4 6 9 Tab:
1 2 3 4 5 6 7 8 9
Koszt konstrukcji kopca
Załóżmy, że n jest liczbą elementów w kopcu, a h jego wysokością.
W(n) = lw * lp
liczba wierzchołków które trzeba być może
poprawić
liczba porównań, które trzeba wtedy wykonać
i n
W
h i
i
h
2
2 )
(
1
Gdyby to było pełne drzewo
binarne Nie trzeba
poprawiać liści
Liczba
wierzchołków na poziomie h-i
Co najwyżej dwa porównania dla każdego elementu na ścieżce do liścia.