Pokročilé haldy prof. Ing. Pavel Tvrdík CSc. Katedra počítačových systémů Fakulta informačních technologií České vysoké učení technické v Praze c Pavel Tvrdík, 2010 Efektivní algoritmy (I-EFA) ZS 2010/11, Přednáška 6 Evropský sociální fond. Praha & EU: Investujeme do vaší budoucnosti prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 1 / 18
inární haldy Opakování inární halda: Opakování inární halda A je uspořádaná dynamická množina, u které jsme popsali v Přednášce 4 následující operace: buildheap(a): Transformuj in-place ÚS A na binární haldu A pomocí heapify(a, i). getmax(a): Vrať ukazatel na prvek s největší hodnotou. extractmax(a): Vyjmi z A prvek s největší hodnotou a vrať ukazatel naň. insert(a, val): Zařaď do haldy A prvek s hodnotou val. Dnes si ukážeme další operace: delete(a, i): Vyjmi z A prvek s indexem i. unionheap(a 1, A 2 ): Vytvoř novou haldu sjednocením hald A 1 a A 2, které jsou touto operací přepsány a vrať ukazatel na ní. prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 2 / 18
inární haldy Vyjmutí prvku Vyjmutí prvku procedure delete(a, i) { (1) if (Heap Size(A) < 1) (2) then error(heapunderflow) (3) else if (Heap Size(A) = 1) (4) then {Heap Size(A) 0; return(a[1])} (5) else { (6) y A[i]; A[i] A[Heap Size[A]]; (7) Heap Size(A) Heap Size(A) 1; (8) heapify(a, i); (9) return(y)} } Věta 1 Časová složitost operace delete je t DE (n) = t HP (n) + Θ(1) = O(log n). prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 3 / 18
inární haldy Vyjmutí prvku Sloučení dvou hald Mějme dvě haldy: A 1 o n 1 prvcích a A 2 o n 2 prvcích, kde n 1 n 2. Předpokládejme, že A 1 a A 2 jsou uložené v paměti za sebou v poli A o velikosti n = n 1 + n 2. Tedy platí, že A 1 = A[1,..., n 1 ] a A 2 = A[n 1 + 1,..., n]. Algoritmus sjednocení dvou hald A 1 a A 2 je operací nad polem A s indexy začátků obou hald 1 a n 1 + 1 procedure unionheap(a, n 1, n 2 ) { (1) Heap Size(A) n 1 + n 2 ; (2) ošetření všech okrajových podmínek; (3) for (i = n 1 downto 1) (4) do heapify(a, i) } prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 4 / 18
Složitost operace nad binární haldou Složitosti operací nad haldou Operace inární halda buildheap(a) Θ(n) getmax(a) O(1) extractmax(a) O(log n) insert(a, val) O(log n) delete(a, i) O(log n) unionheap(a, n 1, n n 1 ) O(n) inární halda nepodporuje efektivně operaci sjednocení (sloučení). Proto se zavádějí sjednotitelné (sloučitelné, mergeable) haldy. Existují 2 řešení, binomiální a Fibonnaciho haldy. Probereme první z nich. prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 5 / 18
inomiální stromy inomiální stromy Definice 2 inomiální strom (NS) k je 1 uzel, pokud k = 0. uspořádaný strom tvořený spojenou dvojicí k 1, kde kořen jednoho k 1 je nejlevějším synem kořene druhého k 1, pokud k > 0. Lemma 3 Pro k, k 0, platí: 1 k má 2 k uzlů a výšku k. 2 V hloubce i, i = 0, 1,..., k, je přesně N(k, i) = ( k i) uzlů. 3 Kořen má stupeň k a žádný jiný uzel nemá vyšší nebo stejný stupeň. 4 Pokud syny kořene číslujeme zleva doprava k 1, k 2,..., 1, 0, pak syn i je kořenem podstromu i. prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 6 / 18
Reprezentace NS Reprezentace NS NS o velikosti n = 8. 19 3 Parent Val Degree Child Sibling 12 17 11 2 5 1 8 1 0 0 13 0 6 0 prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 7 / 18
inomiální haldy inomiální haldy Definice 4 inomiální halda N H je množina binomiálních stromů, která splňuje NH-vlastnost: 1 Každý NS splňuje H-vlastnost: hodnota každého uzlu je menší nebo rovna hodnotě jeho rodiče. 2 Pro dané k existuje v NH nejvýše jeden k. Lemma 5 inomiální halda o n prvcích obsahuje nejvýše log n binomiálních stromů. prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 8 / 18
Reprezentace binomiální haldy Reprezentace binomiální haldy NH o velikosti n = 13. Head[H] 16 9 19 2 7 12 17 13 1 11 5 8 6 16 0 9 2 19 3 Head[H] 2 7 1 0 12 2 17 1 13 0 1 0 11 5 1 0 8 0 6 0 prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 9 / 18
Operace nad binomiálními haldami Nalezení prvku s největší hodnotou procedure getmaxnh(h) { (1) y Null; x Head[H]; max ; (2) while (x Null) (3) do { if (V al[x] > max) (4) then { max V al[x]; y x}; (5) x Sibling[x];} (6) return(y) } Jedná se vlastně o průchod seznamem kořenů. Předpokládá se, že žádný prvek nemá hodnotu. Důsledek 6 Časová složitost algoritmu getmaxnh je O(log n). prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 10 / 18
Operace nad binomiálními haldami Konstrukce k ze dvou k 1 Předpoklady: y a z jsou ukazatele na kořeny dvou NS k 1. z bude ukazatelem na kořen k vzniklého jejich propojením. procedure N Link(y, z) { (1) P arent[y] z; (2) Sibling[y] Child[z]; (3) Child[z] y; (4) Degree[z] Degree[z] + 1; } y 5... z... 5... y 5... z... 6... prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 11 / 18
Operace nad binomiálními haldami Sjednocení dvou binomiálních hald procedure unionnh(h 1, H 2 ) { (1) H initnh(); Head[H] mergenh(h 1, H 2 ); (* sloučení 2 LL*) (2) free the roots of H 1 and H 2 ; (3) if (Head[H] = Null) then return(h); (4) prev x Null; x Head[H]; next x Sibling[x]; (5) while (next x Null) (6) do { if ((Degree[x] Degree[next x]) or Případ (1) (7) ((Sibling[next x] Null) and (8) (Degree[Sibling[next x]] = Degree[x]))) Případ (2) (9) then { prev x x; x next x} (10) else if (V al[x] V al[next x]) Případ (3) (11) then { Sibling[x] Sibling[next x]; (12) N Link(next x, x)} (13) else {if (prev x = Null) Případ (4) (14) then Head[H] next x (15) else Sibling[prev x] next x; (16) N Link(x, next x); x next x}; (17) next x Sibling[x]}; (18) return(h) } prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 12 / 18
Operace nad binomiálními haldami Grafické znázornění 4 případů prev_x prev_x prev_x b>=c x k x prev_x x c>=b next_x a b c d l next_x a b c d k k k x next_x a b c d k k l next_x a b c d k k l (1) (2) (3) (4) prev_x prev_x x next_x a b c d prev_x k prev_x l x next_x a b c d a a k k k x next_x c b k b k l x d next_x c d k k l prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 13 / 18
Operace nad binomiálními haldami Časová složitost algoritmu unionnh Lemma 7 Mějme 2 NH H 1 a H 2 o n 1 a n 2 prvcích a nechť n = n 1 + n 2. Pak časová složitost algoritmu unionnh(h 1, H 2 ) je t HU (n) = O(log n). Důkaz. H 1 obsahuje nejvýše log n 1 kořenů NS a H 2 nejvýše log n 2 kořenů NS. H obsahuje celkem nejvýše ϱ = log n 1 + log n 2 2 log n = O(log n) kořenů. Algoritmus mergenh(h 1, H 2 ) sloučí 2 seřazené seznamy kořenů v čase O(log n). Každá iterace cyklu while provede O(1) operací. Počet iterací cyklu while je ϱ = O(log n), neboť každá z nich buď posune ukazatel x o 1 nebo jeden kořen ze seznamu odstraní. prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 14 / 18
Operace nad binomiálními haldami Vložení nového prvku do NH Předpoklady: Prvek x je alokován v paměti. Hodnota V al[x] je nastavena. Myšlenka řešení: Vytvoří se jednoprvková halda a provede se sjednocení s původní haldou. procedure insertnh(h, x) { (1) H initnh(); (2) P arent[x] Null; Child[x] Null; (3) Sibling[y] Null; Degree[x] 0; (4) Head[H ] x; (5) H unionnh(h, H ) } prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 15 / 18
Operace nad binomiálními haldami Vyjmutí prvku s největší hodnotou procedure extractmaxnh(h) { (1) x kořen s největší hodnotou v seznamu kořenů H; (2) vyjmi tento kořen ze seznamu kořenů; (3) H initnh(); (4) otoč pořadí v seznamu synů x; (5) Head[H ] začátek tohoto výsledného seznamu; (6) H unionnh(h, H ); (7) return(x) } prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 16 / 18
Operace nad binomiálními haldami Zvětšení hodnoty prvku x na novou hodnotu k procedure increasevalnh(h, x, k) { (1) if (k < V al[x]) then error(nová hodnota je menší než stávající); (2) V al[x] k; y x; z P arent[y]; (3) while ((z Null) and (V al[y] > V al[z])) (4) do { exchange(v al[y], V al[z]); (5) y z; z P arent[y]} (6) } prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 17 / 18
Operace nad binomiálními haldami Vyjmutí (odstranění) prvku s danou hodnotou Předpoklad: Všechny prvky x mají V al[x] < +. procedure deletenh(h, x) { (1) increasevalnh(h, x, + ); (2) extractmaxnh(h) } prof. Pavel Tvrdík (FIT ČVUT) Pokročilé haldy I-EFA, 2010, Předn. 6 18 / 18