Heaps und Priority Queues

Slides:



Advertisements
Ähnliche Präsentationen
Randomisierte Algorithmen Präfix Suche und Konsistentes Hashing
Advertisements

Datenstrukturen und Algorithmen
Man bestimme den „minimalen aufspannenden Baum“ des Graphen.
Eine dynamische Menge, die diese Operationen unterstützt,
Minimum Spanning Tree: MST
DNA-Array oder DNA-Chip
DNA-Array oder DNA-Chip
Prof. Dr. S. Albers Prof.Dr.Th Ottmann
Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
GIN2 – 2. Vorlesung, SS04 Prof. Dr. Wolfram Conen
B-Bäume.
Kapitel 6: Klassifizierung von Sortiertechniken
7. Natürliche Binärbäume
Prioritätswarteschlangen
Kapitel 7. Sortier-Algorithmen
Kapitel 5. Stacks und Queues
5. Sortier-Algorithmen Vorbemerkungen:
Synonyme: Stapel, Keller, LIFO-Liste usw.
Gliederung Motivation / Grundlagen Sortierverfahren
Sortieren mit Binären Bäumen
Sortierverfahren Richard Göbel.
Java: Dynamische Datentypen
Sortierverfahren Richard Göbel.
WS Algorithmentheorie 13 - Kürzeste (billigste) Wege Prof. Dr. Th. Ottmann.
WS Algorithmentheorie 05 - Treaps Prof. Dr. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (10 - Suchverfahren) T. Lauer.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (19 - Analyse natürlicher Bäume) Prof. Th. Ottmann.
1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (24 – Fibonacci-Heaps) T. Lauer.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (27 – Kürzeste Wege) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (18 - Bäume: Durchlaufreihenfolgen, Analyse nat. Bäume) Prof. Th. Ottmann.
1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (21 – Kürzeste Wege) T. Lauer.
1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (17 – Fibonacci-Heaps – Analyse) Tobias Lauer.
WS Algorithmentheorie 15 – Fibonacci-Heaps Tobias Lauer.
1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (17 – Fibonacci-Heaps) Tobias Lauer.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (07 - Skiplisten) Prof. Th. Ottmann.
Union-Find-Strukturen
WS Algorithmentheorie 15 – Fibonacci-Heaps Tobias Lauer.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (09 - Weitere Sortierverfahren) Prof. Th. Ottmann.
WS03/041 Binomial Queues Prof. Dr. S. Albers Prof.Dr.Th Ottmann.
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 12 Claudio Moraga, Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
Institut für Kartographie und Geoinformation Diskrete Mathematik I Vorlesung Bäume-
PKJ 2005/1 Stefan Dissmann Rückblick auf 2005 Was zuletzt in 2005 vorgestellt wurde: Klassen mit Attributen, Methoden und Konstruktoren Referenzen auf.
PKJ 2005/1 Stefan Dissmann Zusammenfassung Bisher im Kurs erarbeitete Konzepte(1): Umgang mit einfachen Datentypen Umgang mit Feldern Umgang mit Referenzen.
Externe Datenstruktur lineare Liste
Minimum Spanning Tree: MST
Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
Kapitel 2: Datenstrukturen
PRJ 2007/1 Stefan Dissmann Verkettete datenstruktur: Liste Problem: Liste, die eine beliebige Zahl von Elementen verwaltet Operationen: Erzeugen, Anfügen,
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung
Effiziente Algorithmen
Diskrete Mathematik II
Effiziente Algorithmen Hartmut Klauck Universität Frankfurt SS
Effiziente Algorithmen
Effiziente Algorithmen Hartmut Klauck Universität Frankfurt SS
Information und Kommunikation
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
Übung Datenbanksysteme II Index- strukturen
Informatik 1 Letzte Übung.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Binärbäume.
 Präsentation transkript:

Heaps und Priority Queues Oliver Kohlbacher

Heaps (Halden) Def.: Ein Heap ist eine Datenstruktur in Form eines Baums mit der folgenden Eigenschaft: Jeder Knoten hat einen Schlüssel der extremer (kleiner/größer) oder gleich dem Schlüssel des Elterknoten ist (Heapeigenschaft). 5 14 11 14 11 11 12

Priority Queues (Vorrangwarteschlangen) Def.: Eine Priority Queue PQ ist ein abstrakter Datentyp, der eine Menge von Paaren (key, inf) aus Schlüssel key und Information inf verwaltet und die folgenden Basisoperationen unterstützt: insert – Einfügen eines Elements find_min – Das kleinste Elements zurückgeben remove_min – Entfernen des kleinsten Elements Häufig werden zusätzlich noch die folgenden Operationen benötigt: merge – Verschmelzen zweier Warteschlangen decrease_key – Den Schlüssel eines Elements erniedrigen create – Konstruktion der PQ aus einem unsortierten Feld

Anwendungen von Warteschlangen Sortieren Elemente einfügen Elemente sortiert entnehmen Scheduling Verteile priorisierte Prozesse auf Resource Idee: Wähle Prozess mit höchster Priorität, ausführen „altere“ alle Prozesse in der Schlange Füge den ausgeführten Prozess wieder mit Startpriorität ein Ereignisgesteuerte Simulationen

Ereignisgesteuerte Simulation Beispiel: Paketdienst 1 – Anruf beim Paketdienst (T1 = 0) – erzeugt: 2 – Abholung (T2 = T1 + 60) – erzeugt: 3 – Ankunft im Sortierzentrum (T3 = T2 + 120) 4 – Noch ein Anruf (T4 = 40) – erzeugt: 5 – Abholung (T5 = T4 + 60) – erzeugt: …. 1 4 2 5 3 T1=0 T4 T2 T5 T3

Binary Heap: Interface template <typename Key, typename Inf> class BinaryHeap { public: typedef std::pair<Key, Inf> Item; […] Item& operator [] (int i); // Zugriff auf data void push_back(const Item& item); void push_down(int i); void push_up(int i); bool empty() const; // = (data.empty()) size_t size() const; // = data.size() protected: std::vector<Item> data; // Wurzel in data[0]! };

Priority Queue: Interface template <typename Key, typename Inf> class PriorityQueue { public: typedef std::pair<Key, Inf> Item; void insert(const Item& i); const Item& find_min() const; void delete_min(); void merge(PriorityQueue& pq); void decrease_key(int index, const Key& key); void create(const vector<Item>& array); bool empty() const; BinaryHeap<Key, Inf> heap; };

Implementierung von insert void insert(const Item& item) { // Speichere im nächsten leeren Baumelement heap.push_back(item); // Sortiere bis zur Wurzel neu heap.push_up(heap.size() - 1); } 7 9 25 22 15 30

Implementierung von insert void insert(const Item& item) { // Speichere im nächsten leeren Baumelement heap.push_back(item); // Sortiere bis zur Wurzel neu heap.push_up(heap.size() - 1); } 7 9 25 22 15 30 3

Implementierung von insert void insert(const Item& item) { // Speichere im nächsten leeren Baumelement heap.push_back(item); // Sortiere bis zur Wurzel neu heap.push_up(heap.size() - 1); } 7 9 25 22 15 30 3

Implementierung von insert void insert(const Item& item) { // Speichere im nächsten leeren Baumelement heap.push_back(item); // Sortiere bis zur Wurzel neu heap.push_up(heap.size() - 1); } 7 9 3 22 15 30 25

Implementierung von insert void insert(const Item& item) { // Speichere im nächsten leeren Baumelement heap.push_back(item); // Sortiere bis zur Wurzel neu heap.push_up(heap.size() - 1); } 7 9 3 22 15 30 25

Implementierung von insert void insert(const Item& item) { // Speichere im nächsten leeren Baumelement heap.push_back(item); // Sortiere bis zur Wurzel neu heap.push_up(heap.size() - 1); } Schlimmstenfalls müssen log N Austausch-operationen auf dem Pfad zur Wurzel durchgeführt werden (für einen Heap mit N Elementen)  Laufzeit O(log N) Komplexität von BinaryHeap::push_back?

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen 74 22 25 64 3 19 33

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen 74 22 25 64 3 19 33

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen 74 22 19 64 3 25 33

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen 74 3 19 64 22 25 33

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen 3 74 19 64 22 25 33

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen 3 22 19 64 74 25 33

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen 3 22 19 64 74 25 33

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen Von unten nach oben für jeden Knoten push_down push_down für Höhe h: max. 2 (h – 1) Vergleiche 3 22 64 74 25 33 19 2h - 3 x für Höhe h 2h – 2 x für Höhe h - 1 2h – 1 x für Höhe h - 2 1 x für Heap der Größe 7 2 x für Heap der Größe 3 4 x für Heap der Größe 1

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen Von unten nach oben für jeden Knoten push_down push_down für Höhe h: max. 2 (h – 1) Vergleiche 2h - 3 x für Höhe h 2h – 2 x für Höhe h - 1 2h – 1 x für Höhe h - 2 1 x für Heap der Größe 7 2 x für Heap der Größe 3 4 x für Heap der Größe 1  2h-k

Implementierung von create Naiv: N * insert  O(N log N) Konstruktion ist in Linearzeit möglich! Konstruiere einen Heap mit N = 2h -1 Elementen Von unten nach oben für jeden Knoten push_down push_down für Höhe h: max. 2 (h – 1) Vergleiche Es gibt 2h-k Teilbäume der Höhe k

Implementierung von create push_down für Höhe h: max. 2 (h – 1) Vergleiche Es gibt 2h-k Teilbäume der Höhe k

Implementierung von create Analog kann man eine Schranke für die Konstruktion von unvollständigen binären Heaps herleiten create ist in O(N) möglich void create(const vector<Item>& array) { // Implementierung: Übung! Kopiere Feldinhalt in Heap Für t := (h – 1),…, 1, 0: Für alle Knoten v in Tiefe t: push_down(v) }

Implementierung von find_min const Item& find_min() const { // Konsistenzprüfung if (heap.empty()) throw “Heap is empty!”; // Das kleinste Element liegt in der Wurzel! return heap[0]; } Das kleinste Element liegt immer in der Wurzel des Heaps  find_min benötigt O(1) Zeit Der Heap selbst wird nicht verändert und nur eine Referenz auf das Element zurückgegeben.

Einschub: Exceptions in C++ const Item& find_min() const { if (heap.empty()) throw “Heap is empty!”; […] } try pq.find_min(); catch (const char* message) std::cerr << “Error: “ << message << std::endl;

Implementierung von delete_min void delete_min() { if (heap.empty()) throw “Heap is empty!”; // Letztes Element -> Wurzel, Heap verkleinern heap[0] = heap[heap.size() - 1]; head.pop_back(); // Heapeigenschaft wiederherstellen heap.push_down(0); } Maximal log2N Austauschoperationen Laufzeit O(log N)

Implementierung von decrease_key void decrease_key(int index, const Key& key) { if (index >= heap.size()) throw “illegal index!”; if (heap[index].first <= key) throw “no decrease!”; // Letztes Element -> Wurzel, Heap verkleinern heap[index].first = key; // Heapeigenschaft wiederherstellen heap.push_up(index); } Maximal log N Austauschoperationen Laufzeit O(log N)

Implementierung von merge void merge(const PriorityQueue& pq) { std::vector<Item> tmp(heap.size() + pq.heap.size()); std::copy(heap.data.begin(), heap.data.end(), tmp.begin()); std::copy(pq.heap.data.begin(), pq.heap.data.end()), tmp.begin() + heap.data.size()); create(tmp); } Idee: konkateniere die beiden Heaps, dann wie create std::copy(iterator first, iterator last, iterator to) kopiert den Bereich [first, last) nach [to,…) Der Kopieralgorithmus benötigt Linearzeit, create ebenso  Laufzeit O(N)

Übersicht PQ mit binärem Heap Operation Komplexität insert O(log N) find_min O(1) delete_min decrease_key create O(N) merge

Übersicht PQ mit binärem Heap Operation Komplexität insert O(log N) find_min O(1) delete_min decrease_key create O(N) merge

Binomialbäume B0 B1 B2 B3 B2 B1 B0 Bn Bn-1 Bn-1 Bn-2 B1 B0 Bn ……..

Eigenschaften von Binomialbäumen Satz: Bn hat Höhe n 2n Knoten Grad n in der Wurzel Knoten in Tiefe k

Eigenschaften von Binomialbäumen Satz: Bn hat Höhe n 2n Knoten Grad n in der Wurzel Knoten in Tiefe k B3 Bn-1 Bn-2 B1 B0 Bn Rückgrat B2 B1 B0 B0

Eigenschaften von Binomialbäumen Satz: Bn hat Höhe n 2n Knoten Grad n in der Wurzel Knoten in Tiefe k Bew.: [2] durch Induktion B0 hat einen Knoten |Bn| = 2 |Bn-1| (nach Definition der Binomialbäume)  |Bn| = 2n

Eigenschaften von Binomialbäumen Bn-1 Bn-2 B1 B0 Bn …….. Satz: Bn hat Höhe n 2n Knoten Grad n in der Wurzel Knoten in Tiefe k B3 B2 B1 B0

Eigenschaften von Binomialbäumen Bn Bn-1 Satz: Bn hat Höhe n 2n Knoten Grad n in der Wurzel Knoten in Tiefe k Bew.: [4] durch Induktion Ann.: Bn hat Knk Knoten in Tiefe k n = 0: K00 = 1, keine weiteren Knoten, also K0k = 0 = 8 k > 0

Eigenschaften von Binomialbäumen Bn Bn-1 Satz: Bn hat Höhe n 2n Knoten Grad n in der Wurzel Knoten in Tiefe k Bew.: [4] durch Induktion Ann.: Bn hat Knk Knoten in Tiefe k n = 0: K00 = 1, keine weiteren Knoten, also K0k = 0 = 8 k > 0

Binomial-Heap Def.: Ein Binomial-Heap ist eine Datenstruktur die aus einem Wald von Binomialbäumen besteht. Jeder der Bäume besitzt die Heapeigenschaft und ist mit einem Index k = 0…N versehen. Der Baum mit dem Index k enthält entweder 2k Knoten oder ist leer. B0 B2 B3

Priority Queue mit Binomial-Heaps 7 34 12 B2 B3 B0 min 45 35 23 55 13 87 26 99 87 Binomialbäume in einer zirkulär verketteter Liste min: Zeiger auf Baum mit der kleinsten Wurzel Binomialbäume lassen sich z.B. durch Zeiger auf 1. Kind und nächstes Geschwister implementieren 26

Struktur von Binomial-Heaps Idee: Die N Elemente eines Heaps lassen sich auf eine Menge von Binomialbäumen verteilen, die der Binärdarstellung von N entspricht Einem gesetzten Bit k entspricht ein Binomialbaum Bk, der 2k Knoten enthält Jeder Binomialbaum muß die Heapeigenschaft besitzen  Wurzel ist das Minimum des Baums Ein solcher Heap besitzt höchstens log2N Bäume

Struktur von Binomial-Heaps Idee: Die N Elemente eines Heaps lassen sich auf eine Menge von Binomialbäumen verteilen, die der Binärdarstellung von N entspricht Bsp.: N = 9 = 10012 Heap enthält zwei Bäume: B0 (ein Knoten) und B3 (acht Knoten) B0 B3

Struktur von Binomial-Heaps Jeder Binomialbaum muß die Heapeigenschaft besitzen  Wurzel ist das Minimum des Baums Bsp.: N = 9 = 10012 Heap enthält zwei Bäume: B0 (ein Knoten) und B3 (acht Knoten) B0 B3 5 2 3 7 3 min 4 4 8 5

merge mit Binomial-Heaps Merge-Operation entspricht dem Addieren zweier Binärzahlen Bsp.: zwei Heaps H1, H2 mit N1 = 9 = 10012, N2 = 5 = 1012 1001 + 101 1110 B0 B2 3 5 B0 B3 8 9 5 2 9 3 7 3 4 4 8 5

merge mit Binomial-Heaps for (k = 0; k <= log2(N1 + N2); ++k){ m = #Bk 2 (H1 [ H2); if (m == 1) {// behalten Bk } else if (m == 2){// vereinige beide Bk zu Bk+1} else if (m == 3){// vereinige zwei Bk zu Bk+1, // behalte drittes Bk } } B0 B2 3 5 B0 B3 5 2 8 9 Tree& join(Tree& A, Tree& B) { if (A.root.key < B.root.key) return A.root.insert_child(B.root); else return B.root.insert_child(A.root); } 3 7 3 9 4 4 8 5

merge mit Binomial-Heaps for (k = 0; k <= log2(N1 + N2); ++k){ m = #Bk 2 (H1 [ H2); if (m == 1) {// behalten Bk } else if (m == 2){// vereinige beide Bk zu Bk+1} else if (m == 3){// vereinige zwei Bk zu Bk+1, // behalte drittes Bk } } B2 5 B1 B3 3 2 8 9 Tree& join(Tree& A, Tree& B) { if (A.root.key < B.root.key) return A.root.insert_child(B.root); else return B.root.insert_child(A.root); } 3 7 3 5 9 4 4 8 5

merge mit Binomial-Heaps for (k = 0; k <= log2(N1 + N2); ++k){ m = #Bk 2 (H1 [ H2); if (m == 1) {// behalten Bk } else if (m == 2){// vereinige beide Bk zu Bk+1} else if (m == 3){// vereinige zwei Bk zu Bk+1, // behalte drittes Bk } } 5 9 8 B2 B1 B3 3 2 3 7 3 5 4 4 8 5

merge mit Binomial-Heaps for (k = 0; k <= log2(N1 + N2); ++k){ m = #Bk 2 (H1 [ H2); if (m == 1) {// behalten Bk } else if (m == 2){// vereinige beide Bk zu Bk+1} else if (m == 3){// vereinige zwei Bk zu Bk+1, // behalte drittes Bk } } 5 9 8 B2 B1 B3 3 2 3 7 3 5 4 4 8 5

merge mit Binomial-Heaps for (k = 0; k <= log2(N1 + N2); ++k){ m = #Bk 2 (H1 [ H2); if (m == 1) {// behalten Bk } else if (m == 2){// vereinige beide Bk zu Bk+1} else if (m == 3){// vereinige zwei Bk zu Bk+1, // behalte drittes Bk } } Ergebnis: Heap mit N1 + N2 Knoten: 1001 + 101 1110 min = min(min(H1), min(H2)) B1 B3 3 5 9 8 B2 2 3 7 3 5 min 4 4 8 5

merge mit Binomial-Heaps for (k = 0; k <= log2(N1 + N2); ++k){ m = #Bk 2 (H1 [ H2); if (m == 1) {// behalten Bk } else if (m == 2){// vereinige beide Bk zu Bk+1} else if (m == 3){// vereinige zwei Bk zu Bk+1, // behalte drittes Bk } } Analyse: Join-Operation auf zwei Bäumen erfolgt in O(1) Ergebnis-Heap hat N = N1 + N2 Knoten, max. log2N Bäume log2N Bäume entstanden durch max. log2N Join-Operationen  Komplexität: O(log2N) = O(log2(N1 + N2))

Vergleich binärer Heap und Binomial-Heap Operation Binärer Heap Binomial-Heap insert O(log N) ? find_min O(1) delete_min decrease_key create O(N) merge

insert mit Binomial-Heaps void insert(const Item& item) { Tree trivial_tree(item); this->root = &merge(*this, trivial_tree); } Analyse: Implementierung erfolgt über merge Tree(const Item&) erzeugt B0 mit item in der Wurzel  Komplexität: O(log N) Warum nicht O(1)? „Übertrag“! 1111111 + 1 10000000

create, find_min mit Binomial-Heaps create naiv: schlimmstenfalls N * insert = O(N log N) Bessere Abschätzung Einfügen von N Elementen entspricht binärem Zählen bis N Übungsblatt 5: Amortisierte Analyse des Binärzählers Erzeugen eines trivialen Baums (B0): O(1) merge für zwei Binomialbäume: O(1) Bit setzen/löschen im Binärzähler  elementare Merge-Operation  Komplexität: O(N) find_min ist trivial: wir haben den min-Pointer!  Komplexität: O(1)

delete_min mit Binomial-Heaps 3 5 9 8 B2 2 3 7 3 5 min 4 4 8 5 1. Entferne min aus der Wurzelliste

delete_min mit Binomial-Heaps 3 5 9 8 B2 2 3 7 3 5 min 4 4 8 5 2. Lösche min

delete_min mit Binomial-Heaps 3 B2 5 B2 B1 3 B0 3 7 5 min 8 9 4 4 8 9 5 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 B2 5 B2 B1 3 7 5 min 8 9 4 4 8 9 5 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 B2 5 B2 7 8 B1 3 5 min 8 9 4 4 9 5 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 B2 5 7 B2 3 5 min 8 8 9 4 4 9 5 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 B2 5 7 B2 3 5 min 8 8 9 4 4 9 5 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 B2 5 7 B2 3 5 min 8 8 9 4 4 9 5 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 5 9 8 7 B2 3 5 min 8 4 4 5 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 7 B2 3 5 9 8 5 min 8 4 4 5 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 7 B2 3 5 5 min 8 4 4 8 9 5 9 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 7 3 4 5 B2 5 9 8 5 min 8 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 B0 3 3 7 4 4 5 9 8 5 min 8 5 3. Füge Kinder von min ein

delete_min mit Binomial-Heaps 3 4 5 B2 3 B0 3 7 5 9 8 5 min 8 4. Neues min Element suchen

delete_min mit Binomial-Heaps void delete_min() { // 1. Entferne min aus Wurzelliste root_list.erase(min); // 2. Lösche min Tree* child = min->first_child; delete min; // 3. Füge Kinder ein while (child != 0) Tree* next_child = child->next; merge(*child); child = next_child; } // 4. Finde neues Minimum min = minimum(); // Geht über Wurzelliste, findet minimum

delete_min mit Binomial-Heaps void delete_min() { // 1. Entferne min aus Wurzelliste O(1) root_list.erase(min); // 2. Lösche min O(1) Tree* child = min->first_child; ´ delete min; // 3. Füge Kinder ein O(log N) while (child != 0) Tree* next_child = child->next; merge(*child); child = next_child; } // 4. Finde neues Minimum O(log N) min = minimum(); // Geht über Wurzelliste, findet minimum

decrease_key mit Binomial-Heaps 3 B2 2 5 3 7 3 5 min 8 9 4 4 8 9 5 1. Fall: decrease_key auf min

decrease_key mit Binomial-Heaps 3 B2 1 5 3 7 3 5 min 8 9 4 4 8 9 5 1. Fall: decrease_key auf min - O(1)

decrease_key mit Binomial-Heaps 3 B2 2 5 3 7 3 5 min 8 9 4 4 8 9 5 2. Fall: decrease_key auf bel. Wurzel

decrease_key mit Binomial-Heaps 1 B2 2 5 3 7 3 5 min 8 9 4 4 8 9 5 2. Fall: decrease_key auf bel. Wurzel - O(1)

decrease_key mit Binomial-Heaps 3 B2 2 5 3 7 3 5 min 8 9 4 4 8 9 5 3. Fall: decrease_key auf bel. Element

decrease_key mit Binomial-Heaps 3 B2 2 5 3 7 3 5 min 8 9 4 4 8 1 5 3. Fall: decrease_key auf bel. Element

decrease_key mit Binomial-Heaps 3 B1 2 7 8 4 5 B3 min B2 5 8 9 1 3. Fall: decrease_key auf bel. Element

decrease_key mit Binomial-Heaps 3 B1 2 7 8 4 5 B3 min B2 5 1 9 8 3. Fall: decrease_key auf bel. Element

decrease_key mit Binomial-Heaps 3 B1 2 7 8 4 5 B3 min B2 1 5 9 8 3. Fall: decrease_key auf bel. Element

decrease_key mit Binomial-Heaps 3 B2 2 1 3 7 3 5 min 5 9 4 4 8 8 5 3. Fall: decrease_key auf bel. Element

decrease_key mit Binomial-Heaps 3 B2 2 1 3 7 3 5 min 5 9 4 4 8 8 5 3. Fall: decrease_key auf bel. Element - O(log N)

Vergleich binärer Heap und Binomial-Heap Operation Binärer Heap Binomial-Heap insert O(log N) find_min O(1) delete_min decrease_key create O(N) merge

Die Heap-Algorithmen der STL vector<int> my_heap(20); […] std::make_heap(my_heap.begin(), my_heap.end()); // Hinzufügen my_heap.push_back(item); std::push_heap(my_heap.begin(), my_heap.end()); Die STL definiert die Standardoperationen auf binären Heaps im Header <algorithm> Die Algorithmen arbeiten auf beliebigen Containern mit wahlfreiemn Zugriff – sie benötigen nur entsprechende Iteratoren

Die STL-Klasse priority_queue // Aus STL header <queue>: template <typename T, typename Container, typename Compare> class priority_queue { public: […] void push(const value_type& item); // insert const_reference top() const; // find_min void pop(); // insert }; priority_queue ist im Header <queue> definiert Die Klasse ist ein Adapter, d.h sie setzt auf einen bereits implementierten Container auf (vector<T>) Die Implementierung basiert auf binären Heaps Durch Wahl von Compare wird die Ordnung bestimmt