Heapsort Datenstrukturen und Algorithmen Vorlesung 8: Heapsort (K6) Joost-Pieter Katoen Lehrstuhl für Informatik 2 Software Modeling and Verification Group http://moves.rwth-aachen.de/teaching/ss-15/dsal/ 7. Mai 2015 Joost-Pieter Katoen Datenstrukturen und Algorithmen 1/23 Heapsort Übersicht 1 Heaps 2 Heapaufbau 3 Heapsort 4 Anwendung: Prioritätswarteschlangen Joost-Pieter Katoen Datenstrukturen und Algorithmen 2/23 Heapsort Heaps Übersicht 1 Heaps 2 Heapaufbau 3 Heapsort 4 Anwendung: Prioritätswarteschlangen Joost-Pieter Katoen Datenstrukturen und Algorithmen 3/23 Heapsort Heaps Heaps Heap (Haufen) Ein Heap ist ein Binärbaum, der Elemente mit Schlüsseln enthält und in ein Array eingebettet ist. Die Heap-Bedingung für Max-Heaps fordert: Joost-Pieter Katoen Datenstrukturen und Algorithmen 4/23 Heapsort Heaps Heaps Heap (Haufen) Ein Heap ist ein Binärbaum, der Elemente mit Schlüsseln enthält und in ein Array eingebettet ist. Die Heap-Bedingung für Max-Heaps fordert: I Der Schlüssel eines Knotens ist stets größer als (bzw. mindestens so groß wie) die Schlüssel seiner Kinder. Joost-Pieter Katoen Datenstrukturen und Algorithmen 4/23 Heapsort Heaps Heaps Heap (Haufen) Ein Heap ist ein Binärbaum, der Elemente mit Schlüsseln enthält und in ein Array eingebettet ist. Die Heap-Bedingung für Max-Heaps fordert: I Der Schlüssel eines Knotens ist stets größer als (bzw. mindestens so groß wie) die Schlüssel seiner Kinder. Weiter gilt: I Alle Ebenen, abgesehen von evtl. der untersten, sind komplett gefüllt. Joost-Pieter Katoen Datenstrukturen und Algorithmen 4/23 Heapsort Heaps Heaps Heap (Haufen) Ein Heap ist ein Binärbaum, der Elemente mit Schlüsseln enthält und in ein Array eingebettet ist. Die Heap-Bedingung für Max-Heaps fordert: I Der Schlüssel eines Knotens ist stets größer als (bzw. mindestens so groß wie) die Schlüssel seiner Kinder. Weiter gilt: I Alle Ebenen, abgesehen von evtl. der untersten, sind komplett gefüllt. I Die Blätter befinden sich damit alle auf einer (höchstens zwei) Ebene(n). Joost-Pieter Katoen Datenstrukturen und Algorithmen 4/23 Heapsort Heaps Heaps Heap (Haufen) Ein Heap ist ein Binärbaum, der Elemente mit Schlüsseln enthält und in ein Array eingebettet ist. Die Heap-Bedingung für Max-Heaps fordert: I Der Schlüssel eines Knotens ist stets größer als (bzw. mindestens so groß wie) die Schlüssel seiner Kinder. Weiter gilt: I Alle Ebenen, abgesehen von evtl. der untersten, sind komplett gefüllt. I Die Blätter befinden sich damit alle auf einer (höchstens zwei) Ebene(n). I Die Blätter der untersten Ebene sind linksbündig angeordnet. Joost-Pieter Katoen Datenstrukturen und Algorithmen 4/23 Heapsort Heaps Arrayeinbettung eines Heaps Arrayeinbettung Beispiel 0 Das Array a wird wie folgt als Binärbaum aufgefasst: I 16 1 2 14 Die Wurzel liegt in a[0]. 10 3 4 5 8 7 7 6 9 3 8 9 2 4 1 16 14 10 8 7 9 3 2 4 1 0 Joost-Pieter Katoen 1 2 3 4 5 Datenstrukturen und Algorithmen 6 7 8 9 5/23 Heapsort Heaps Arrayeinbettung eines Heaps Arrayeinbettung Beispiel 0 Das Array a wird wie folgt als Binärbaum aufgefasst: I Die Wurzel liegt in a[0]. I Das linke Kind von a[i] liegt in a[2 * i + 1]. 16 1 2 14 10 3 4 5 8 7 7 6 9 3 8 9 2 4 1 16 14 10 8 7 9 3 2 4 1 0 Joost-Pieter Katoen 1 2 3 4 5 Datenstrukturen und Algorithmen 6 7 8 9 5/23 Heapsort Heaps Arrayeinbettung eines Heaps Arrayeinbettung Beispiel 0 Das Array a wird wie folgt als Binärbaum aufgefasst: I Die Wurzel liegt in a[0]. I Das linke Kind von a[i] liegt in a[2 * i + 1]. I Das rechte Kind von a[i] liegt in a[2 * i + 2]. 16 1 10 3 4 5 8 7 7 6 9 3 8 9 2 4 1 16 14 10 8 7 9 3 2 4 1 0 Joost-Pieter Katoen 2 14 1 2 3 4 5 Datenstrukturen und Algorithmen 6 7 8 9 5/23 Heapsort Heaps Arrayeinbettung eines Heaps Arrayeinbettung Beispiel 0 Das Array a wird wie folgt als Binärbaum aufgefasst: I Die Wurzel liegt in a[0]. I Das linke Kind von a[i] liegt in a[2 * i + 1]. I Das rechte Kind von a[i] liegt in a[2 * i + 2]. 16 1 10 3 4 5 8 7 7 6 9 3 8 9 2 4 1 16 14 10 8 7 9 3 2 4 1 0 I 2 14 1 2 3 4 5 6 7 8 9 Durch die möglichst vollständige Füllung der Ebenen werden „Löcher“ im Array vermieden. Joost-Pieter Katoen Datenstrukturen und Algorithmen 5/23 Heapsort Heaps Arrayeinbettung eines Heaps Arrayeinbettung Beispiel 0 Das Array a wird wie folgt als Binärbaum aufgefasst: I Die Wurzel liegt in a[0]. I Das linke Kind von a[i] liegt in a[2 * i + 1]. I Das rechte Kind von a[i] liegt in a[2 * i + 2]. 16 1 2 14 10 3 4 5 8 7 7 6 9 3 8 9 2 4 1 16 14 10 8 7 9 3 2 4 1 0 1 2 3 4 5 6 7 8 9 I Durch die möglichst vollständige Füllung der Ebenen werden „Löcher“ im Array vermieden. I Vergrößert man den Baum um ein Element, so wird das Array gerade um ein Element länger. Joost-Pieter Katoen Datenstrukturen und Algorithmen 5/23 Heapsort Heaps Heaps – Eigenschaften Lemma Vergrößert man den Schlüssel der Wurzel, dann bleibt der Baum ein Heap. Joost-Pieter Katoen Datenstrukturen und Algorithmen 6/23 Heapsort Heaps Heaps – Eigenschaften Lemma Vergrößert man den Schlüssel der Wurzel, dann bleibt der Baum ein Heap. Lemma Jedes Array „ist ein Heap“ ab Position b n2 c. Joost-Pieter Katoen Datenstrukturen und Algorithmen 6/23 Heapsort Heaps Heaps – Eigenschaften Lemma Vergrößert man den Schlüssel der Wurzel, dann bleibt der Baum ein Heap. Lemma Jedes Array „ist ein Heap“ ab Position b n2 c. I Ein Heap hat b n2 c innere Knoten. Joost-Pieter Katoen Datenstrukturen und Algorithmen 6/23 Heapsort Heapaufbau Übersicht 1 Heaps 2 Heapaufbau 3 Heapsort 4 Anwendung: Prioritätswarteschlangen Joost-Pieter Katoen Datenstrukturen und Algorithmen 7/23 Heapsort Heapaufbau Naiver Heapaufbau 2 7 10 3 9 14 4 8 16 15 2 7 10 3 14 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 2 7 10 3 9 14 4 8 16 15 2 7 10 3 14 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 7 2 10 3 9 14 4 8 16 15 7 2 10 3 14 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 7 2 10 3 9 14 4 8 16 15 7 2 10 3 14 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 10 2 7 3 9 14 4 8 16 15 10 2 7 3 14 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 10 2 7 3 9 14 4 8 16 15 10 2 7 3 14 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 10 3 7 2 9 14 4 8 16 15 10 3 7 2 14 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 10 3 7 2 9 14 4 8 16 15 10 3 7 2 14 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 10 14 7 2 9 3 4 8 16 15 10 14 7 2 3 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 14 10 7 2 9 3 4 8 16 15 14 10 7 2 3 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 14 10 7 2 9 3 4 8 16 15 14 10 7 2 3 8 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 14 10 8 2 9 3 4 7 16 15 14 10 8 2 3 7 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 14 10 8 2 9 3 4 7 16 15 14 10 8 2 3 7 16 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 14 10 16 2 9 3 4 7 8 15 14 10 16 2 3 7 8 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 16 10 14 2 9 3 4 7 8 15 16 10 14 2 3 7 8 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 16 10 14 2 9 3 4 7 8 15 16 10 14 2 3 7 8 9 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 16 10 14 9 2 3 4 7 8 15 16 10 14 9 3 7 8 2 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 16 10 14 9 2 3 4 7 8 15 16 10 14 9 3 7 8 2 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 16 10 14 9 2 3 4 7 8 15 16 10 14 9 3 7 8 2 4 15 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 16 10 14 9 2 15 4 7 8 3 16 10 14 9 15 7 8 2 4 3 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau 16 15 14 9 2 10 4 7 8 3 16 15 14 9 10 7 8 2 4 3 Heapaufbau, naiv Der Heap wird von oben nach unten (top-down) aufgebaut, indem I ein neues Element möglichst weit links angefügt wird und I rekursiv nach oben getauscht wird, solange es größer als sein Elternknoten ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 8/23 Heapsort Heapaufbau Naiver Heapaufbau – Algorithmus und Analyse 1 2 3 4 5 6 7 8 9 10 void bubble(int E[], int pos) { while (pos > 0) { int parent = (pos - 1) / 2; if (E[parent] > E[pos]) { break; } swap(E[parent], E[pos]); pos = parent; } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 9/23 Heapsort Heapaufbau Naiver Heapaufbau – Algorithmus und Analyse 1 2 3 4 5 6 7 8 9 10 void bubble(int E[], int pos) { while (pos > 0) { int parent = (pos - 1) / 2; if (E[parent] > E[pos]) { break; } swap(E[parent], E[pos]); pos = parent; } } Die Höhe k eines Heaps mit n Elementen ist beschränkt durch: n 6 2k+1 − 1 Joost-Pieter Katoen ⇒ k = blog2 (n)c Datenstrukturen und Algorithmen 9/23 Heapsort Heapaufbau Naiver Heapaufbau – Algorithmus und Analyse 1 2 3 4 5 6 7 8 9 10 void bubble(int E[], int pos) { while (pos > 0) { int parent = (pos - 1) / 2; if (E[parent] > E[pos]) { break; } swap(E[parent], E[pos]); pos = parent; } } Die Höhe k eines Heaps mit n Elementen ist beschränkt durch: n 6 2k+1 − 1 I ⇒ k = blog2 (n)c Damit kostet jedes Einfügen k ≈ log2 (n) Vergleiche. Joost-Pieter Katoen Datenstrukturen und Algorithmen 9/23 Heapsort Heapaufbau Naiver Heapaufbau – Algorithmus und Analyse 1 2 3 4 5 6 7 8 9 10 void bubble(int E[], int pos) { while (pos > 0) { int parent = (pos - 1) / 2; if (E[parent] > E[pos]) { break; } swap(E[parent], E[pos]); pos = parent; } } Die Höhe k eines Heaps mit n Elementen ist beschränkt durch: n 6 2k+1 − 1 I ⇒ k = blog2 (n)c Damit kostet jedes Einfügen k ≈ log2 (n) Vergleiche. ⇒ Zum Aufbau eines Heaps mit n Elementen benötigt man Θ(n · log(n)) Vergleiche. Joost-Pieter Katoen Datenstrukturen und Algorithmen 9/23 Heapsort Heapaufbau Naiver Heapaufbau – Algorithmus und Analyse 1 2 3 4 5 6 7 8 9 10 void bubble(int E[], int pos) { while (pos > 0) { int parent = (pos - 1) / 2; if (E[parent] > E[pos]) { break; } swap(E[parent], E[pos]); pos = parent; } } Die Höhe k eines Heaps mit n Elementen ist beschränkt durch: n 6 2k+1 − 1 I ⇒ k = blog2 (n)c Damit kostet jedes Einfügen k ≈ log2 (n) Vergleiche. ⇒ Zum Aufbau eines Heaps mit n Elementen benötigt man Θ(n · log(n)) Vergleiche. Es geht effizienter: heapify (auch: sink, fixheap) Joost-Pieter Katoen Datenstrukturen und Algorithmen [Floyd 1964] 9/23 Heapsort Heapaufbau Heapify – Strategie Betrachte E[i] unter der Annahme, dass der rechte und linke Teilbaum bereits ein Heap ist. I E[i] kann kleiner als seine Kinder sein. Joost-Pieter Katoen Datenstrukturen und Algorithmen 10/23 Heapsort Heapaufbau Heapify – Strategie Betrachte E[i] unter der Annahme, dass der rechte und linke Teilbaum bereits ein Heap ist. I E[i] kann kleiner als seine Kinder sein. I Wir wollen die beiden Teilbäume – Heaps – zusammen mit E[i] zu einem (Gesamt-)Heap verschmelzen. Joost-Pieter Katoen Datenstrukturen und Algorithmen 10/23 Heapsort Heapaufbau Heapify – Strategie Betrachte E[i] unter der Annahme, dass der rechte und linke Teilbaum bereits ein Heap ist. I E[i] kann kleiner als seine Kinder sein. I Wir wollen die beiden Teilbäume – Heaps – zusammen mit E[i] zu einem (Gesamt-)Heap verschmelzen. I Dazu lassen wir E[i] in den Heap hineinsinken, sodass der Teilbaum mit Wurzel E[i] ein Heap ist. Joost-Pieter Katoen Datenstrukturen und Algorithmen 10/23 Heapsort Heapaufbau Heapify – Strategie Betrachte E[i] unter der Annahme, dass der rechte und linke Teilbaum bereits ein Heap ist. I E[i] kann kleiner als seine Kinder sein. I Wir wollen die beiden Teilbäume – Heaps – zusammen mit E[i] zu einem (Gesamt-)Heap verschmelzen. I Dazu lassen wir E[i] in den Heap hineinsinken, sodass der Teilbaum mit Wurzel E[i] ein Heap ist. Heapify I Finde das Maximum der Werte E[i] und seiner Kinder. Joost-Pieter Katoen Datenstrukturen und Algorithmen 10/23 Heapsort Heapaufbau Heapify – Strategie Betrachte E[i] unter der Annahme, dass der rechte und linke Teilbaum bereits ein Heap ist. I E[i] kann kleiner als seine Kinder sein. I Wir wollen die beiden Teilbäume – Heaps – zusammen mit E[i] zu einem (Gesamt-)Heap verschmelzen. I Dazu lassen wir E[i] in den Heap hineinsinken, sodass der Teilbaum mit Wurzel E[i] ein Heap ist. Heapify I Finde das Maximum der Werte E[i] und seiner Kinder. I Ist E[i] bereits das größte Element, dann ist dieser gesamte Teilbaum auch ein Heap. Fertig. Joost-Pieter Katoen Datenstrukturen und Algorithmen 10/23 Heapsort Heapaufbau Heapify – Strategie Betrachte E[i] unter der Annahme, dass der rechte und linke Teilbaum bereits ein Heap ist. I E[i] kann kleiner als seine Kinder sein. I Wir wollen die beiden Teilbäume – Heaps – zusammen mit E[i] zu einem (Gesamt-)Heap verschmelzen. I Dazu lassen wir E[i] in den Heap hineinsinken, sodass der Teilbaum mit Wurzel E[i] ein Heap ist. Heapify I Finde das Maximum der Werte E[i] und seiner Kinder. I Ist E[i] bereits das größte Element, dann ist dieser gesamte Teilbaum auch ein Heap. Fertig. I Andernfalls tausche E[i] mit dem größten Element und führe Heapify in diesem Unterbaum weiter aus. Joost-Pieter Katoen Datenstrukturen und Algorithmen 10/23 Heapsort Heapaufbau Heapify – Algorithmus und Beispiel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void heapify(int E[], int n, int pos) { int next = 2 * pos + 1; while (next < n) { 0 if (next + 1 < n && 12 E[next + 1] > E[next]) { 1 next = next + 1; 16 } 3 4 5 if (E[pos] >= E[next]) { 14 7 9 break; } 7 8 9 2 8 1 swap(E[pos], E[next]); pos = next; next = 2 * pos + 1; 12 16 10 14 7 9 3 } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 2 10 6 3 2 8 1 11/23 Heapsort Heapaufbau Heapify – Algorithmus und Beispiel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void heapify(int E[], int n, int pos) { int next = 2 * pos + 1; while (next < n) { 0 if (next + 1 < n && 16 E[next + 1] > E[next]) { 1 next = next + 1; 12 } 3 4 5 if (E[pos] >= E[next]) { 14 7 9 break; } 7 8 9 2 8 1 swap(E[pos], E[next]); pos = next; next = 2 * pos + 1; 16 12 10 14 7 9 3 } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 2 10 6 3 2 8 1 11/23 Heapsort Heapaufbau Heapify – Algorithmus und Beispiel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void heapify(int E[], int n, int pos) { int next = 2 * pos + 1; while (next < n) { 0 if (next + 1 < n && 16 E[next + 1] > E[next]) { 1 next = next + 1; 14 } 3 4 5 if (E[pos] >= E[next]) { 12 7 9 break; } 7 8 9 2 8 1 swap(E[pos], E[next]); pos = next; next = 2 * pos + 1; 16 14 10 12 7 9 3 } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 2 10 6 3 2 8 1 11/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 7 10 3 9 1 2 3 4 5 14 4 8 16 15 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 7 10 3 9 1 2 3 4 5 14 4 8 16 15 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 7 10 3 9 1 2 3 4 5 15 4 8 16 14 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 7 10 3 9 1 2 3 4 5 15 4 8 16 14 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 7 10 9 3 1 2 3 4 5 15 4 8 16 14 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 7 10 9 3 1 2 3 4 5 15 4 8 16 14 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 7 16 9 3 1 2 3 4 5 15 4 8 10 14 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 7 16 9 3 1 2 3 4 5 15 4 8 10 14 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 15 16 9 3 1 2 3 4 5 7 4 8 10 14 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 15 16 9 3 1 2 3 4 5 14 4 8 10 7 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 2 15 16 9 3 1 2 3 4 5 14 4 8 10 7 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 16 15 2 9 3 1 2 3 4 5 14 4 8 10 7 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Heapaufbau – Algorithmus und Beispiel Strategie: Wandle das Array von unten nach oben (bottom-up) in einen Heap um. 16 15 10 9 3 1 2 3 4 5 14 4 8 2 7 void buildHeap(int E[]) { for (int i = E.length / 2 - 1; i >= 0; i--) { heapify(E, E.length, i); } } Nach jedem Aufruf von heapify(E, E.length, i) sind die Knoten i, . . . , E.length - 1 schon Wurzeln von Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 12/23 Heapsort Heapaufbau Konstruktion eines Heaps Lemma Der Algorithmus buildHeap ist korrekt und terminiert. Joost-Pieter Katoen Datenstrukturen und Algorithmen 13/23 Heapsort Heapaufbau Konstruktion eines Heaps Lemma Der Algorithmus buildHeap ist korrekt und terminiert. I Initialisierung: Jeder Knoten i = bn/2c, bn/2c + 1, . . . ist ein Blatt und damit Wurzel eines trivialen Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 13/23 Heapsort Heapaufbau Konstruktion eines Heaps Lemma Der Algorithmus buildHeap ist korrekt und terminiert. I Initialisierung: Jeder Knoten i = bn/2c, bn/2c + 1, . . . ist ein Blatt und damit Wurzel eines trivialen Heaps. I Schleifeninvariante: Zu Beginn der for-Schleife ist jeder Knoten i+1, . . . , E .length die Wurzel eines Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 13/23 Heapsort Heapaufbau Konstruktion eines Heaps Lemma Der Algorithmus buildHeap ist korrekt und terminiert. I Initialisierung: Jeder Knoten i = bn/2c, bn/2c + 1, . . . ist ein Blatt und damit Wurzel eines trivialen Heaps. I Schleifeninvariante: Zu Beginn der for-Schleife ist jeder Knoten i+1, . . . , E .length die Wurzel eines Heaps. I In jeder Iteration sind alle Kinder des Knotens i bereits Wurzeln eines Heaps (Schleifeninvariante). Joost-Pieter Katoen Datenstrukturen und Algorithmen 13/23 Heapsort Heapaufbau Konstruktion eines Heaps Lemma Der Algorithmus buildHeap ist korrekt und terminiert. I Initialisierung: Jeder Knoten i = bn/2c, bn/2c + 1, . . . ist ein Blatt und damit Wurzel eines trivialen Heaps. I Schleifeninvariante: Zu Beginn der for-Schleife ist jeder Knoten i+1, . . . , E .length die Wurzel eines Heaps. I In jeder Iteration sind alle Kinder des Knotens i bereits Wurzeln eines Heaps (Schleifeninvariante). ⇒ Bedingung für den Aufruf von heapify ist erfüllt. I Dekrementierung von i stellt Schleifeninvariante wieder her. Joost-Pieter Katoen Datenstrukturen und Algorithmen 13/23 Heapsort Heapaufbau Konstruktion eines Heaps Lemma Der Algorithmus buildHeap ist korrekt und terminiert. I Initialisierung: Jeder Knoten i = bn/2c, bn/2c + 1, . . . ist ein Blatt und damit Wurzel eines trivialen Heaps. I Schleifeninvariante: Zu Beginn der for-Schleife ist jeder Knoten i+1, . . . , E .length die Wurzel eines Heaps. I In jeder Iteration sind alle Kinder des Knotens i bereits Wurzeln eines Heaps (Schleifeninvariante). ⇒ Bedingung für den Aufruf von heapify ist erfüllt. I Dekrementierung von i stellt Schleifeninvariante wieder her. I Terminierung: Bei i = 0 ist gemäß Schleifeninvariante jeder Knoten 1, 2, . . . , n die Wurzel eines Heaps. Joost-Pieter Katoen Datenstrukturen und Algorithmen 13/23 Heapsort Heapsort Übersicht 1 Heaps 2 Heapaufbau 3 Heapsort 4 Anwendung: Prioritätswarteschlangen Joost-Pieter Katoen Datenstrukturen und Algorithmen 14/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 17 25 3 19 6 69 17 12 4 8 2 13 34 0 41 26 17 25 19 17 8 3 6 69 12 4 2 13 34 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 17 25 3 19 6 69 17 12 4 8 2 13 34 0 41 26 17 25 19 17 8 3 6 69 12 4 2 13 34 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 17 25 3 19 6 69 17 12 4 8 2 13 34 0 41 26 17 25 19 17 8 3 6 69 12 4 2 13 34 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 17 25 3 19 6 69 17 12 4 34 2 13 8 0 41 26 17 25 19 17 34 3 6 69 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 17 25 3 19 6 69 17 12 4 34 2 13 8 0 41 26 17 25 19 17 34 3 6 69 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 17 25 3 19 6 69 17 12 4 34 2 13 8 0 41 26 17 25 19 17 34 3 6 69 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 17 25 3 69 6 19 17 12 4 34 2 13 8 0 41 26 17 25 69 17 34 3 6 19 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 17 25 3 69 6 19 17 12 4 34 2 13 8 0 41 26 17 25 69 17 34 3 6 19 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 17 25 3 69 6 19 17 12 4 34 2 13 8 0 41 26 17 25 69 17 34 3 6 19 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 34 25 3 69 6 19 17 12 4 17 2 13 8 0 41 26 34 25 69 17 17 3 6 19 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 34 25 3 69 6 19 17 12 4 17 2 13 8 0 41 26 34 25 69 17 17 3 6 19 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 69 34 25 3 26 6 19 17 12 4 17 2 13 8 0 41 69 34 25 26 17 17 3 6 19 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 69 34 25 3 26 6 19 17 12 4 17 2 13 8 0 41 69 34 25 26 17 17 3 6 19 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 69 41 34 25 3 26 6 19 17 12 4 17 2 13 8 0 69 41 34 25 26 17 17 3 6 19 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 69 41 34 25 3 26 6 19 17 12 4 17 2 13 8 0 69 41 34 25 26 17 17 3 6 19 12 4 2 13 8 0 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 0 41 34 25 3 26 6 19 17 12 4 17 2 13 8 0 41 34 25 26 17 17 3 6 19 12 4 2 13 8 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 0 34 25 3 26 6 19 17 12 4 17 2 13 8 41 0 34 25 26 17 17 3 6 19 12 4 2 13 8 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 34 25 3 0 6 19 17 12 4 17 2 13 8 41 26 34 25 0 17 17 3 6 19 12 4 2 13 8 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 34 25 3 19 6 0 17 12 4 17 2 13 8 41 26 34 25 19 17 17 3 6 0 12 4 2 13 8 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 41 26 34 25 3 19 6 0 17 12 4 17 2 13 8 41 26 34 25 19 17 17 3 6 0 12 4 2 13 8 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 8 26 34 25 3 19 6 0 17 12 4 17 2 13 8 26 34 25 19 17 17 3 6 0 12 4 2 13 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 34 26 8 25 3 19 6 0 17 12 4 17 2 13 34 26 8 25 19 17 17 3 6 0 12 4 2 13 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 34 26 17 25 3 19 6 0 8 12 4 17 2 13 34 26 17 25 19 8 17 3 6 0 12 4 2 13 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 34 26 17 25 3 19 6 0 8 12 4 17 2 13 34 26 17 25 19 8 17 3 6 0 12 4 2 13 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 13 26 17 25 3 19 6 0 8 12 4 17 2 13 26 17 25 19 8 17 3 6 0 12 4 2 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 26 13 17 25 3 19 6 0 8 12 4 17 2 26 13 17 25 19 8 17 3 6 0 12 4 2 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 26 25 17 13 3 19 6 0 8 12 4 17 2 26 25 17 13 19 8 17 3 6 0 12 4 2 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 26 25 17 13 3 19 6 0 8 12 4 17 2 26 25 17 13 19 8 17 3 6 0 12 4 2 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 2 25 17 13 3 19 6 0 8 12 17 4 2 25 17 13 19 8 17 3 6 0 12 4 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 25 2 17 13 3 19 6 0 8 12 17 4 25 2 17 13 19 8 17 3 6 0 12 4 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 25 19 17 13 3 2 6 0 8 12 17 4 25 19 17 13 2 8 17 3 6 0 12 4 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 25 19 17 13 3 12 6 0 8 2 17 4 25 19 17 13 12 8 17 3 6 0 2 4 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 25 19 17 13 3 12 6 0 8 2 17 4 25 19 17 13 12 8 17 3 6 0 2 4 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 4 19 17 13 3 12 6 0 8 17 2 4 19 17 13 12 8 17 3 6 0 2 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 19 4 17 13 3 12 6 0 8 17 2 19 4 17 13 12 8 17 3 6 0 2 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 19 13 17 4 3 12 6 0 8 17 2 19 13 17 4 12 8 17 3 6 0 2 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 19 13 17 6 3 12 4 0 8 17 2 19 13 17 6 12 8 17 3 4 0 2 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 19 13 17 6 3 12 4 0 8 17 2 19 13 17 6 12 8 17 3 4 0 2 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 2 13 17 6 3 12 4 8 17 0 2 13 17 6 12 8 17 3 4 0 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 17 13 2 6 3 12 4 8 17 0 17 13 2 6 12 8 17 3 4 0 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 17 13 17 6 3 12 4 8 2 0 17 13 17 6 12 8 2 3 4 0 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 17 13 17 6 3 12 4 8 2 0 17 13 17 6 12 8 2 3 4 0 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 0 13 6 3 17 12 8 2 4 0 13 17 6 12 8 2 3 4 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 17 13 6 3 0 12 8 2 4 17 13 0 6 12 8 2 3 4 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 17 13 6 3 8 12 0 2 4 17 13 8 6 12 0 2 3 4 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 17 13 6 3 8 12 0 2 4 17 13 8 6 12 0 2 3 4 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 4 13 6 8 12 0 2 3 4 13 8 6 12 0 2 3 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 13 4 6 8 12 0 2 3 13 4 8 6 12 0 2 3 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 13 12 6 8 4 0 2 3 13 12 8 6 4 0 2 3 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 13 12 6 8 4 0 2 3 13 12 8 6 4 0 2 3 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 3 12 6 8 4 0 2 3 12 8 6 4 0 2 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 12 3 6 8 4 0 2 12 3 8 6 4 0 2 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 12 6 3 8 4 0 2 12 6 8 3 4 0 2 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 12 6 3 8 4 0 2 12 6 8 3 4 0 2 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 2 6 3 8 4 0 2 6 8 3 4 0 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 8 6 3 2 4 0 8 6 2 3 4 0 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 8 6 3 2 4 0 8 6 2 3 4 0 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 0 6 3 2 4 0 6 2 3 4 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 6 0 3 2 4 6 0 2 3 4 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 6 4 3 2 0 6 4 2 3 0 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 6 4 3 2 0 6 4 2 3 0 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 0 4 2 3 0 4 2 3 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 4 0 2 3 4 0 2 3 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 4 3 2 0 4 3 2 0 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 4 3 2 0 4 3 2 0 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 0 3 2 0 3 2 4 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 3 0 2 3 0 2 4 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 3 0 2 3 0 2 4 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 2 0 2 0 3 4 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 2 0 2 0 3 4 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Algorithmus und Beispiel 0 0 2 3 4 6 8 12 13 17 17 19 25 26 34 41 69 1 2 3 4 5 6 7 void heapSort(int E[]) { buildHeap(E); for (int i = E.length - 1; i > 0; i--) { swap(E[0], E[i]); heapify(E, i, 0); } } Joost-Pieter Katoen Datenstrukturen und Algorithmen 15/23 Heapsort Heapsort Heapsort – Analyse I Die Worst-Case Komplexität von Heapify ist maximal 2 · blog2 (n)c für n Knoten. Joost-Pieter Katoen Datenstrukturen und Algorithmen 16/23 Heapsort Heapsort Heapsort – Analyse I Die Worst-Case Komplexität von Heapify ist maximal 2 · blog2 (n)c für n Knoten. I für einen Heap mit Level k, gibt es 2 · k Vergleiche im Worst-Case Joost-Pieter Katoen Datenstrukturen und Algorithmen 16/23 Heapsort Heapsort Heapsort – Analyse I Die Worst-Case Komplexität von Heapify ist maximal 2 · blog2 (n)c für n Knoten. I I für einen Heap mit Level k, gibt es 2 · k Vergleiche im Worst-Case Die Worst-Case Komplexität von buildHeap ist Θ(n) (Beweis: spätere Folie) Joost-Pieter Katoen Datenstrukturen und Algorithmen 16/23 Heapsort Heapsort Heapsort – Analyse I Die Worst-Case Komplexität von Heapify ist maximal 2 · blog2 (n)c für n Knoten. I I für einen Heap mit Level k, gibt es 2 · k Vergleiche im Worst-Case Die Worst-Case Komplexität von buildHeap ist Θ(n) (Beweis: spätere Folie) I Für Heapsort erhalten wir somit: W (n) = n−1 X ! 2 · blog2 (i)c + n i=1 Joost-Pieter Katoen Datenstrukturen und Algorithmen 16/23 Heapsort Heapsort Heapsort – Analyse I Die Worst-Case Komplexität von Heapify ist maximal 2 · blog2 (n)c für n Knoten. I I für einen Heap mit Level k, gibt es 2 · k Vergleiche im Worst-Case Die Worst-Case Komplexität von buildHeap ist Θ(n) (Beweis: spätere Folie) I Für Heapsort erhalten wir somit: W (n) = n−1 X ! 2 · blog2 (i)c + n i=1 n−1 X 6 2· ! log2 (n) + n i=1 Joost-Pieter Katoen Datenstrukturen und Algorithmen 16/23 Heapsort Heapsort Heapsort – Analyse I Die Worst-Case Komplexität von Heapify ist maximal 2 · blog2 (n)c für n Knoten. I I für einen Heap mit Level k, gibt es 2 · k Vergleiche im Worst-Case Die Worst-Case Komplexität von buildHeap ist Θ(n) (Beweis: spätere Folie) I Für Heapsort erhalten wir somit: W (n) = n−1 X ! 2 · blog2 (i)c + n i=1 n−1 X 6 2· ! log2 (n) + n i=1 = 2 · (n − 1) · log2 (n) + n Joost-Pieter Katoen Datenstrukturen und Algorithmen 16/23 Heapsort Heapsort Heapsort – Analyse I Die Worst-Case Komplexität von Heapify ist maximal 2 · blog2 (n)c für n Knoten. I I für einen Heap mit Level k, gibt es 2 · k Vergleiche im Worst-Case Die Worst-Case Komplexität von buildHeap ist Θ(n) (Beweis: spätere Folie) I Für Heapsort erhalten wir somit: W (n) = n−1 X ! 2 · blog2 (i)c + n i=1 n−1 X 6 2· ! log2 (n) + n i=1 = 2 · (n − 1) · log2 (n) + n ⇒ W (n) ∈ O(n · log(n)) Joost-Pieter Katoen Datenstrukturen und Algorithmen 16/23 Heapsort Heapsort Heapsort – Analyse I Die Worst-Case Komplexität von Heapify ist maximal 2 · blog2 (n)c für n Knoten. I I für einen Heap mit Level k, gibt es 2 · k Vergleiche im Worst-Case Die Worst-Case Komplexität von buildHeap ist Θ(n) (Beweis: spätere Folie) I Für Heapsort erhalten wir somit: W (n) = n−1 X ! 2 · blog2 (i)c + n i=1 n−1 X 6 2· ! log2 (n) + n i=1 = 2 · (n − 1) · log2 (n) + n ⇒ W (n) ∈ O(n · log(n)) I Zusätzlicher Speicherplatzbedarf ist konstant (lokale Variablen). Joost-Pieter Katoen Datenstrukturen und Algorithmen 16/23 Heapsort Heapsort Heapsort – Heapeigenschaften Lemma Ein n-elementiger Heap hat die Höhe blog2 (n)c. Joost-Pieter Katoen Datenstrukturen und Algorithmen 17/23 Heapsort Heapsort Heapsort – Heapeigenschaften Lemma Ein n-elementiger Heap hat die Höhe blog2 (n)c. Lemma Ein Heap hat maximal dn/2h+1 e Knoten mit der Höhe h. Joost-Pieter Katoen Datenstrukturen und Algorithmen 17/23 Heapsort Heapsort Heapsort – Heapeigenschaften Lemma Ein n-elementiger Heap hat die Höhe blog2 (n)c. Lemma Ein Heap hat maximal dn/2h+1 e Knoten mit der Höhe h. Beweise siehe Übung 4. Joost-Pieter Katoen Datenstrukturen und Algorithmen 17/23 Heapsort Heapsort Heapsort – Komplexitätsanalyse Die Worst-Case Komplexität von buildHeap ist Θ(n) Beweis: Joost-Pieter Katoen Datenstrukturen und Algorithmen 18/23 Heapsort Heapsort Heapsort – Komplexitätsanalyse Die Worst-Case Komplexität von buildHeap ist Θ(n) Beweis: I Die Laufzeit von Heapify für einen Knoten der Höhe h ist in O(h). Joost-Pieter Katoen Datenstrukturen und Algorithmen 18/23 Heapsort Heapsort Heapsort – Komplexitätsanalyse Die Worst-Case Komplexität von buildHeap ist Θ(n) Beweis: I Die Laufzeit von Heapify für einen Knoten der Höhe h ist in O(h). I dn/2h+1 e = Anzahl der Knoten mit Höhe h. Daraus folgt für buildHeap: Joost-Pieter Katoen Datenstrukturen und Algorithmen 18/23 Heapsort Heapsort Heapsort – Komplexitätsanalyse Die Worst-Case Komplexität von buildHeap ist Θ(n) Beweis: I Die Laufzeit von Heapify für einen Knoten der Höhe h ist in O(h). I dn/2h+1 e = Anzahl der Knoten mit Höhe h. Daraus folgt für buildHeap: blog2 (n)c X h=0 Joost-Pieter Katoen n 2h+1 O(h) Datenstrukturen und Algorithmen 18/23 Heapsort Heapsort Heapsort – Komplexitätsanalyse Die Worst-Case Komplexität von buildHeap ist Θ(n) Beweis: I Die Laufzeit von Heapify für einen Knoten der Höhe h ist in O(h). I dn/2h+1 e = Anzahl der Knoten mit Höhe h. Daraus folgt für buildHeap: blog2 (n)c X h=0 Joost-Pieter Katoen n 2h+1 blog2 (n)c O(h) = On X h=0 h 2h Datenstrukturen und Algorithmen 18/23 Heapsort Heapsort Heapsort – Komplexitätsanalyse Die Worst-Case Komplexität von buildHeap ist Θ(n) Beweis: I Die Laufzeit von Heapify für einen Knoten der Höhe h ist in O(h). I dn/2h+1 e = Anzahl der Knoten mit Höhe h. Daraus folgt für buildHeap: blog2 (n)c X h=0 Joost-Pieter Katoen n 2h+1 blog2 (n)c O(h) = On X h=0 ∞ h X h 1/2 | = =2 h h 2 2 (1 − 1/2)2 h=0 Datenstrukturen und Algorithmen 18/23 Heapsort Heapsort Heapsort – Komplexitätsanalyse Die Worst-Case Komplexität von buildHeap ist Θ(n) Beweis: I Die Laufzeit von Heapify für einen Knoten der Höhe h ist in O(h). I dn/2h+1 e = Anzahl der Knoten mit Höhe h. Daraus folgt für buildHeap: blog2 (n)c X h=0 n 2h+1 blog2 (n)c O(h) = On X h=0 ∞ X h = O n 2h h=0 Joost-Pieter Katoen ∞ h X h 1/2 | = =2 h h 2 2 (1 − 1/2)2 h=0 ! Datenstrukturen und Algorithmen 18/23 Heapsort Heapsort Heapsort – Komplexitätsanalyse Die Worst-Case Komplexität von buildHeap ist Θ(n) Beweis: I Die Laufzeit von Heapify für einen Knoten der Höhe h ist in O(h). I dn/2h+1 e = Anzahl der Knoten mit Höhe h. Daraus folgt für buildHeap: blog2 (n)c X h=0 n 2h+1 blog2 (n)c X O(h) = On h=0 ∞ X h = O n 2h h=0 ∞ h X h 1/2 | = =2 h h 2 2 (1 − 1/2)2 h=0 ! = O(n) Joost-Pieter Katoen Datenstrukturen und Algorithmen 18/23 Heapsort Heapsort Heapsort – Zusammenfassung I Heapsort sortiert in O(n· log(n)). Joost-Pieter Katoen Datenstrukturen und Algorithmen 19/23 Heapsort Heapsort Heapsort – Zusammenfassung I Heapsort sortiert in O(n· log(n)). I Heapsort ist ein in-place Algorithmus. Joost-Pieter Katoen Datenstrukturen und Algorithmen 19/23 Heapsort Heapsort Heapsort – Zusammenfassung I Heapsort sortiert in O(n· log(n)). I Heapsort ist ein in-place Algorithmus. I Heapsort ist nicht stabil. Joost-Pieter Katoen Datenstrukturen und Algorithmen 19/23 Heapsort Anwendung: Prioritätswarteschlangen Übersicht 1 Heaps 2 Heapaufbau 3 Heapsort 4 Anwendung: Prioritätswarteschlangen Joost-Pieter Katoen Datenstrukturen und Algorithmen 20/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (I) I Betrachte Elemente, die mit einem Schlüssel (key) versehen sind. Joost-Pieter Katoen Datenstrukturen und Algorithmen 21/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (I) I Betrachte Elemente, die mit einem Schlüssel (key) versehen sind. I Jeder Schlüssel sei höchstens an ein Element vergeben. Joost-Pieter Katoen Datenstrukturen und Algorithmen 21/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (I) I Betrachte Elemente, die mit einem Schlüssel (key) versehen sind. I Jeder Schlüssel sei höchstens an ein Element vergeben. I Schlüssel werden als Priorität betrachtet. Joost-Pieter Katoen Datenstrukturen und Algorithmen 21/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (I) I Betrachte Elemente, die mit einem Schlüssel (key) versehen sind. I Jeder Schlüssel sei höchstens an ein Element vergeben. I Schlüssel werden als Priorität betrachtet. I Die Elemente werden nach ihrer Priorität sortiert. Joost-Pieter Katoen Datenstrukturen und Algorithmen 21/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (II) Prioritätswarteschlange (priority queue) I void insert(PriorityQueue pq, Element e, int k) fügt das Element e mit dem Schlüssel k in pq ein. Joost-Pieter Katoen Datenstrukturen und Algorithmen 22/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (II) Prioritätswarteschlange (priority queue) I void insert(PriorityQueue pq, Element e, int k) fügt das Element e mit dem Schlüssel k in pq ein. I Element getMin(PriorityQueue pq) gibt das Element mit dem kleinsten Schlüssel zurück; benötigt nicht-leere pq. Joost-Pieter Katoen Datenstrukturen und Algorithmen 22/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (II) Prioritätswarteschlange (priority queue) I void insert(PriorityQueue pq, Element e, int k) fügt das Element e mit dem Schlüssel k in pq ein. I Element getMin(PriorityQueue pq) gibt das Element mit dem kleinsten Schlüssel zurück; benötigt nicht-leere pq. I void delMin(PriorityQueue pq) entfernt das Element mit dem kleinsten Schlüssel; benötigt nicht-leere pq. Joost-Pieter Katoen Datenstrukturen und Algorithmen 22/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (II) Prioritätswarteschlange (priority queue) I void insert(PriorityQueue pq, Element e, int k) fügt das Element e mit dem Schlüssel k in pq ein. I Element getMin(PriorityQueue pq) gibt das Element mit dem kleinsten Schlüssel zurück; benötigt nicht-leere pq. I void delMin(PriorityQueue pq) entfernt das Element mit dem kleinsten Schlüssel; benötigt nicht-leere pq. I Element getElt(PriorityQueue pq, int k) gibt das Element e mit dem Schlüssel k aus pq zurück; k muss in pq enthalten sein. Joost-Pieter Katoen Datenstrukturen und Algorithmen 22/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (II) Prioritätswarteschlange (priority queue) I void insert(PriorityQueue pq, Element e, int k) fügt das Element e mit dem Schlüssel k in pq ein. I Element getMin(PriorityQueue pq) gibt das Element mit dem kleinsten Schlüssel zurück; benötigt nicht-leere pq. I void delMin(PriorityQueue pq) entfernt das Element mit dem kleinsten Schlüssel; benötigt nicht-leere pq. I Element getElt(PriorityQueue pq, int k) gibt das Element e mit dem Schlüssel k aus pq zurück; k muss in pq enthalten sein. I void decrKey(PriorityQueue pq, Element e, int k) setzt den Schlüssel von Element e auf k; e muss in pq enthalten sein. k muss außerdem kleiner als der bisherige Schlüssel von e sein. Joost-Pieter Katoen Datenstrukturen und Algorithmen 22/23 Heapsort Anwendung: Prioritätswarteschlangen Erinnerung: Die Prioritätswarteschlange (II) Prioritätswarteschlange (priority queue) I void insert(PriorityQueue pq, Element e, int k) fügt das Element e mit dem Schlüssel k in pq ein. I Element getMin(PriorityQueue pq) gibt das Element mit dem kleinsten Schlüssel zurück; benötigt nicht-leere pq. I void delMin(PriorityQueue pq) entfernt das Element mit dem kleinsten Schlüssel; benötigt nicht-leere pq. I Element getElt(PriorityQueue pq, int k) gibt das Element e mit dem Schlüssel k aus pq zurück; k muss in pq enthalten sein. I void decrKey(PriorityQueue pq, Element e, int k) setzt den Schlüssel von Element e auf k; e muss in pq enthalten sein. k muss außerdem kleiner als der bisherige Schlüssel von e sein. Mit Heaps ist eine effiziente Implementierung möglich. Joost-Pieter Katoen Datenstrukturen und Algorithmen 22/23 Heapsort Anwendung: Prioritätswarteschlangen Drei Prioritätswarteschlangenimplementierungen Implementierung Operation isEmpty(pq) insert(pq,e,k) getMin(pq) delMin(pq) getElt(pq,k) decrKey(pq,e,k) ∗ † unsortiertes Array Θ(1) Θ(1) Θ(n) Θ(n)∗ Θ(n) Θ(1) sortiertes Array Θ(1) Θ(n)∗ Θ(1) Θ(1) Θ(log(n))† Θ(n)∗ Heap Θ(1) Θ(log(n)) Θ(1) Θ(log(n)) Θ(n) Θ(log(n)) Beinhaltet das Verschieben aller Elemente „rechts“ von k. Mittels binärer Suche. Joost-Pieter Katoen Datenstrukturen und Algorithmen 23/23