14. Sortieren II Heapsort. Heapsort. [Max-]Heap 7. Heapsort, Quicksort, Mergesort. Binärer Baum mit folgenden Eigenschaften

Ähnliche Dokumente
8. Sortieren II. 8.1 Heapsort. Heapsort. [Max-]Heap 6. Heapsort, Quicksort, Mergesort. Binärer Baum mit folgenden Eigenschaften

Heapsort, Quicksort, Mergesort. 8. Sortieren II

Heapsort, Quicksort, Mergesort. 8. Sortieren II

18. Natürliche Suchbäume

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle

Das Suchproblem 4. Suchen Das Auswahlproblem Suche in Array

9. Natürliche Suchbäume

Das Suchproblem 4. Suchen Das Auswahlproblem Suche in Array

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle

3. Suchen. Das Suchproblem. Suche in Array. Lineare Suche. 1 n. i = n Gegeben Menge von Datensätzen.

9. Rekursion. 1 falls n 1 n (n 1)!, andernfalls. Experiment: Die Türme von Hanoi. Links Mitte Rechts. Mathematische Rekursion

Kap. 3: Sortieren (3)

Abschnitt: Algorithmendesign und Laufzeitanalyse

8. A & D - Heapsort. Werden sehen, wie wir durch geschicktes Organsieren von Daten effiziente Algorithmen entwerfen können.

18. Natürliche Suchbäume

Grundlagen: Algorithmen und Datenstrukturen

10. Sortieren III. Untere Schranken für das vergleichsbasierte Sortieren, Radix- und Bucketsort

A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.2 Quicksort. A7.

3.2. Divide-and-Conquer-Methoden

10. Wiederholung Natürliche Suchbäume und Heaps

Kapitel 6 Elementare Sortieralgorithmen

Algorithmen und Datenstrukturen

Heapsort / 1 A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]

Übung Algorithmen und Datenstrukturen

6 Quicksort. die mittlere Laufzeit Θ(n log n) beträgt und. die in der asymptotischen Notation verborgenen Konstanten sehr klein sind.

Algorithmen und Datenstrukturen

Auswählen nach Rang (Selektion)

Heapsort. 1. Erstelle aus dem gegebenen Array einen Max-Heap (DownHeap) 2. Tausche erstes und letztes Element des Arrays

Übung zu Algorithmen und Datenstrukturen (für ET/IT)

Sortieren II / HeapSort Heaps

in eine Folge ai, so daß bezgl. einer Ordnung gilt: a a, j < n

Suchen und Sortieren Sortieren. Heaps

Suchen und Sortieren Sortieren. Mergesort

Tutoraufgabe 1 (Sortieren): Lösung: Datenstrukturen und Algorithmen SS14 Lösung - Übung 4

Copyright, Page 1 of 7 Heapsort

Heapsort. Dr. Michael Brinkmeier (TU Ilmenau) Algorithmen und Datenstrukturen / 50

Formaler. Gegeben: Elementfolge s = e 1,...,e n. s ist Permutation von s e 1 e n für eine lineare Ordnung ` '

Proseminar Effiziente Algorithmen

Übung Algorithmen I

21. Greedy Algorithmen. Aktivitätenauswahl, Fractional Knapsack Problem, Huffman Coding Cormen et al, Kap. 16.1, 16.3

Definition Ein Heap (priority queue) ist eine abstrakte Datenstruktur mit folgenden Kennzeichen:

Datenstrukturen & Algorithmen

12. Java Fehler und Ausnahmen

Datenstrukturen & Algorithmen

Algorithmen und Datenstrukturen Heapsort

Übersicht. Datenstrukturen und Algorithmen. Divide-and-Conquer. Übersicht. Vorlesung 9: Quicksort (K7)

Übung zu Algorithmen und Datenstrukturen (für ET/IT)

Algorithmen und Datenstrukturen

Datenstrukturen und Algorithmen Beispiellösung zu Heimübungsblatt 7. Abbildung 1: Das Array A als Baum (vgl. Foliensatz 16, Folie 3)

Algorithmen und Datenstrukturen

Algo-Animation. Konstruktion der Partition: eigentliche Kunst / Arbeit bei Quicksort. Resultat: Partition A=A 1 WA 2 A 1 W A 2.

Algorithmen und Datenstrukturen

Informatik II, SS 2016

Tutoraufgabe 1 (Sortieralgorithmus):

Proseminar Effiziente Algorithmen

Algorithmen und Datenstrukturen

Sortieren & Co. KIT Institut für Theoretische Informatik

Algorithmen und Datenstrukturen SoSe 2008 in Trier. Henning Fernau Universität Trier

Werden sehen, wie wir durch geschicktes Organsieren von Daten effiziente Algorithmen entwerfen können.

Algorithmen und Datenstrukturen

Übersicht. Einfache Verfahren MergeSort Untere Schranke QuickSort Selektieren Schnelleres Sortieren Externes Sortieren. 6 Sortieren.

1.3 Erinnerung: Mergesort

Kap. 3 Sortieren. 7. VO DAP2 SS Mai Vorlesung am Do 7.5. entfällt wegen FVV um 14 Uhr HeapSort ff 3.1.

Algorithmen I. Prof. Jörn Müller-Quade Institut für Theoretische Informatik Web:

1 Raumwechsel: Gr. 15 (Do 10-12, F-235) ab sofort in G Studie zum Arbeitsverhalten von Studierenden unter Leitung

Beispiellösung zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 5

Algorithmen und Datenstrukturen (Th. Ottmann und P. Widmayer) Folien: Einfache Sortierverfahren Autor: Stefan Edelkamp

Kapitel 8 Fortgeschrittene Sortieralgorithmen

Informatik II, SS 2018

7. Sortieren Lernziele. 7. Sortieren

Mergesort. Inhaltsverzeichnis. Veranschaulichung der Funktionsweise. aus Wikipedia, der freien Enzyklopädie

Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen

Kapitel 2. Weitere Beispiele Effizienter Algorithmen

Algorithmen und Datenstrukturen

Übung Algorithmen und Datenstrukturen

Algorithmen & Komplexität

Praktische Informatik I - Algorithmen und Datenstrukturen Wintersemester 2006/07

Algorithmen und Datenstrukturen

8.1.3 Operation Build-Max-Heap Operation zur Konstruktion eines Heaps Eingabe: Feld A[1..n], n = länge(a) BUILD-MAX-HEAP (A)

Technische Universität München

Abschnitt 19: Sortierverfahren

Algorithmen & Komplexität

Informatik II, SS 2018

2. Felder (Arrays) 2.1 Suchen in Feldern. lineares Suchen: siehe Kapitel 1. Binäres Suchen. Vor.: Elemente (z.b. aufsteigend) sortiert

Datenstrukturen Kurzanleitung

Algorithmen I - Tutorium 28 Nr. 2

Aufgabe 8. 1 Arbeitsweise illustrieren. 2 Korrektheitsbeweis führen. 3 Laufzeitanalyse durchführen.

QuickSort ist ein Sortieralgorithmus, der auf der Idee des Teile & Beherrsche beruht, und das gegebene Array an Ort und Stelle (in place) sortiert

4. Sortieren 4.1 Vorbemerkungen

Algorithmen und Datenstrukturen

Übersicht. Datenstrukturen und Algorithmen. Übersicht. Heaps. Vorlesung 8: Heapsort (K6) Joost-Pieter Katoen. 7. Mai 2015

2. Effizienz von Algorithmen

Algorithmen und Datenstrukturen (für ET/IT)

Informatik II, SS 2016

Sortieralgorithmen. Jan Pöschko. 18. Januar Problemstellung Definition Warum Sortieren?... 2

Algorithmen I. Tutorium 1-5. Sitzung. Dennis Felsing

Grundzüge von Algorithmen und Datenstrukturen, WS 15/16: Lösungshinweise zum 13. Übungsblatt

Quicksort ist ein Divide-and-Conquer-Verfahren.

Kapitel 3: Sortierverfahren Gliederung

Transkript:

Heapsort, Quicksort, Mergesort 14. Sortieren II 14.1 Heapsort [Ottman/Widmayer, Kap. 2.3, Cormen et al, Kap. 6] 397 398 Heapsort [Max-]Heap 7 Inspiration von Selectsort: Schnelles Einfügen Binärer Baum mit folgenden Eigenschaften 1 vollständig, bis auf die letzte Ebene Wurzel Inspiration von Insertionsort: Schnelles Finden der Position? Können wir das beste der beiden Welten haben?! Ja, aber nicht ganz so einfach... 2 Lücken des Baumes in der letzten Ebene höchstens rechts. 3 Heap-Bedingung: Max-(Min-)Heap: Schlüssel eines Kindes kleiner (grösser) als der des Vaters 16 12 15 3 2 8 11 14 Blätter 17 Vater Kind 7 Heap (Datenstruktur), nicht: wie in Heap und Stack (Speicherallokation) 399 400

Heap und Array Rekursive Heap-Struktur Baum Array: 1 Kinder(i) = {2i, 2i + 1} Vater(i) = i/2 2 3 Vater 16 4 12 5 15 6 Kinder 17 7 3 8 2 9 8 10 11 11 14 12 [1] [2] [3] 16 12 15 17 [4] [5] [6] [7] 3 2 8 11 14 [8] [9] [10] [11] [12] Ein Heap besteht aus zwei Teilheaps: 16 12 15 3 2 8 11 14 17 Abhängig von Startindex! 8 8 Für Arrays, die bei 0 beginnen: {2i, 2i + 1} {2i + 1, 2i + 2}, i/2 (i 1)/2 401 402 Einfügen Maximum entfernen 21 Füge neues Element an erste freie Stelle ein. Verletzt Heap Eigenschaft potentiell. Stelle Heap Eigenschaft wieder her: Sukzessives Aufsteigen. Anzahl Operationen im schlechtesten Fall: O(log n) 16 12 15 3 2 8 11 14 16 12 21 17 17 Ersetze das Maximum durch das unterste rechte Element. Stelle Heap Eigenschaft wieder her: Sukzessives Absinken (in Richtung des grösseren Kindes). Anzahl Operationen im schlechtesten Fall: O(log n) 16 12 15 17 3 2 8 11 14 16 14 12 15 17 3 2 8 11 14 15 3 2 8 11 403 404

Algorithmus Versickern(A, i, m) Input : Array A mit Heapstruktur für die Kinder von i. Letztes Element m. Output : Array A mit Heapstruktur für i mit letztem Element m. while 2i m do j 2i; // j linkes Kind if j < m and A[j] < A[j + 1] then j j + 1; // j rechtes Kind mit grösserem Schlüssel if A[i] < A[j] then swap(a[i], A[j]) i j; // weiter versickern else i m; // versickern beendet Heap Sortieren A[1,..., n] ist Heap. Solange n > 1 swap(a[1], A[n]) Versickere(A, 1, n 1); n n 1 7 6 4 5 1 2 Tauschen 2 6 4 5 1 7 Versickern 6 5 4 2 1 7 Tauschen 1 5 4 2 6 7 Versickern 5 4 2 1 6 7 Tauschen 1 4 2 5 6 7 Versickern 4 1 2 5 6 7 Tauschen 2 1 4 5 6 7 Versickern 2 1 4 5 6 7 Tauschen 1 2 4 5 6 7 405 406 Heap erstellen Algorithmus HeapSort(A, n) Beobachtung: Jedes Blatt eines Heaps ist für sich schon ein korrekter Heap. Folgerung: Induktion von unten! Input : Array A der Länge n. Output : A sortiert. for i n/2 downto 1 do Versickere(A, i, n); // Nun ist A ein Heap. for i n downto 2 do swap(a[1], A[i]) Versickere(A, 1, i 1) // Nun ist A sortiert. 407 408

Analyse: Sortieren eines Heaps Versickere durchläuft maximal log n Knoten. An jedem Knoten 2 Schlüsselvergleiche. Heap sortieren kostet im schlechtesten Fall 2n log n Vergleiche. Anzahl der Bewegungen vom Heap Sortieren auch O(n log n). Analyse: Heap bauen Aufrufe an Versickern: n/2. Also Anzahl Vergleiche und Bewegungen v(n) O(n log n). Versickerpfade aber im Mittel viel kürzer, also sogar: v(n) = log n h=0 n log n c h O(n 2 h+1 h=0 s(x) := k=0 kxk = x (1 x) 2 (0 < x < 1). Mit s( 1 2 ) = 2: h 2 h) v(n) O(n). 409 410 Mergesort (Sortieren durch Verschmelzen) 14.2 Mergesort [Ottman/Widmayer, Kap. 2.4, Cormen et al, Kap. 2.3], Divide and Conquer! Annahme: Zwei Hälften eines Arrays A bereits sortiert. Folgerung: Minimum von A kann mit 2 Vergleichen ermittelt werden. Iterativ: Sortierung des so vorsortierten A in O(n). 411 412

Merge Algorithmus Merge(A, l, m, r) 1 4 7 9 16 2 3 10 11 12 1 2 3 4 7 9 10 11 12 16 Input : Array A der Länge n, Indizes 1 l m r n. A[l,..., m], A[m + 1,..., r] sortiert Output : A[l,..., r] sortiert 1 B new Array(r l + 1) 2 i l; j m + 1; k 1 3 while i m and j r do 4 if A[i] A[j] then B[k] A[i]; i i + 1 5 else B[k] A[j]; j j + 1 6 k k + 1; 7 while i m do B[k] A[i]; i i + 1; k k + 1 8 while j r do B[k] A[j]; j j + 1; k k + 1 9 for k l to r do A[k] B[k l + 1] 413 414 Korrektheit Hypothese: Nach k Durchläufen der Schleife von Zeile 3 ist B[1,..., k] sortiert und B[k] A[i], falls i m und B[k] A[j] falls j r. Beweis per Induktion: Induktionsanfang: Das leere Array B[1,..., 0] ist trivialerweise sortiert. Induktionsschluss (k k + 1): obda A[i] A[j], i m, j r. B[1,..., k] ist nach Hypothese sortiert und B[k] A[i]. Nach B[k + 1] A[i] ist B[1,..., k + 1] sortiert. B[k + 1] = A[i] A[i + 1] (falls i + 1 m) und B[k + 1] A[j] falls j r. k k + 1, i i + 1: Aussage gilt erneut. 415 Analyse (Merge) Lemma Wenn: Array A der Länge n, Indizes 1 l < r n. m = (l + r)/2 und A[l,..., m], A[m + 1,..., r] sortiert. Dann: im Aufruf Merge(A, l, m, r) werden Θ(r l) viele Schlüsselbewegungen und Vergleiche durchgeführt. Beweis: (Inspektion des Algorithmus und Zählen der Operationen). 416

Mergesort Algorithmus Rekursives 2-Wege Mergesort(A, l, r) 5 2 6 1 8 4 3 9 5 2 6 1 8 4 3 9 5 2 6 1 8 4 3 9 5 2 6 1 8 4 3 9 2 5 1 6 4 8 3 9 1 2 5 6 3 4 8 9 1 2 3 4 5 6 8 9 Split Split Split Merge Merge Merge Input : Array A der Länge n. 1 l r n Output : Array A[l,..., r] sortiert. if l < r then m (l + r)/2 // Mittlere Position Mergesort(A, l, m) // Sortiere vordere Hälfte Mergesort(A, m + 1, r) // Sortiere hintere Hälfte Merge(A, l, m, r) // Verschmelzen der Teilfolgen 417 4 Analyse Rekursionsgleichung für die Anzahl Vergleiche und Schlüsselbewegungen: n n C(n) = C( ) + C( ) + Θ(n) Θ(n log n) 2 2 Algorithmus StraightMergesort(A) Rekursion vermeiden: Verschmelze Folgen der Länge 1, 2, 4... direkt Input : Array A der Länge n Output : Array A sortiert length 1 while length < n do // Iteriere über die Längen n right 0 while right + length < n do // Iteriere über die Teilfolgen left right + 1 middle left + length 1 right min(middle + length, n) Merge(A, left, middle, right) length length 2 419 4

Analyse Natürliches 2-Wege Mergesort Wie rekursives Mergesort führt reines 2-Wege-Mergesort immer Θ(n log n) viele Schlüsselvergleiche und -bewegungen aus. Beobachtung: Obige Varianten nutzen nicht aus, wenn vorsortiert ist und führen immer Θ(n log n) viele Bewegungen aus.? Wie kann man teilweise vorsortierte Folgen besser sortieren?! Rekursives Verschmelzen von bereits vorsortierten Teilen (Runs) von A. 421 4 Natürliches 2-Wege Mergesort 5 6 2 4 8 3 9 7 1 2 4 5 6 8 3 7 9 1 2 3 4 5 6 7 8 9 1 1 2 3 4 5 6 7 8 9 423 Algorithmus NaturalMergesort(A) Input : Array A der Länge n > 0 Output : Array A sortiert repeat r 0 while r < n do l r + 1 m l; while m < n and A[m + 1] A[m] do m m + 1 if m < n then r m + 1; while r < n and A[r + 1] A[r] do r r + 1 Merge(A, l, m, r); else r n until l = 1 424

Analyse Im besten Fall führt natürliches Mergesort nur n 1 Vergleiche durch!? Ist es auch im Mittel asymptotisch besser als StraightMergesort?! Nein. Unter Annahme der Gleichverteilung der paarweise unterschiedlichen Schlüssel haben wir im Mittel n/2 Stellen i mit k i > k i+1, also n/2 Runs und sparen uns lediglich einen Durchlauf, also n Vergleiche. 14.3 Quicksort [Ottman/Widmayer, Kap. 2.2, Cormen et al, Kap. 7] Natürliches Mergesort führt im schlechtesten und durchschnittlichen Fall Θ(n log n) viele Vergleiche und Bewegungen aus. 425 426 Quicksort Quicksort (willkürlicher Pivot)? Was ist der Nachteil von Mergesort?! Benötigt Θ(n) Speicherplatz für das Verschmelzen.? Wie könnte man das Verschmelzen einsparen?! Sorge dafür, dass jedes Element im linken Teil kleiner ist als im rechten Teil.? Wie?! Pivotieren und Aufteilen! 2 4 5 6 8 3 7 9 1 2 1 3 6 8 5 7 9 4 1 2 3 4 5 8 7 9 6 1 2 3 4 5 6 7 9 8 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 427 428

Algorithmus Quicksort(A[l,..., r] Zur Erinnerung: Algorithmus Partition(A[l,..., r], p) Input : Array A der Länge n. 1 l r n. Output : Array A, sortiert zwischen l und r. if l < r then Wähle Pivot p A[l,..., r] k Partition(A[l,..., r], p) Quicksort(A[l,..., k 1]) Quicksort(A[k + 1,..., r]) Input : Array A, welches den Sentinel p im Intervall [l, r] mindestens einmal enthält. Output : Array A partitioniert um p. Rückgabe der Position von p. while l < r do while A[l] < p do l l + 1 while A[r] > p do r r 1 swap(a[l], A[r]) if A[l] = A[r] then // Nur für nicht paarweise verschiedene Schlüssel l l + 1 return l-1 429 430 Analyse: Anzahl Vergleiche Analyse: Anzahl Vertauschungen Bester Fall. Pivotelement = Median; Anzahl Vergleiche: T (n) = 2T (n/2) + c n, T (1) = 0 T (n) O(n log n) Schlechtester Fall. Pivotelement = Minimum oder Maximum; Anzahl Vergleiche: T (n) = T (n 1) + c n, T (1) = 0 T (n) Θ(n 2 ) Resultat eines Aufrufes an Partition (Pivot 3): 2 1 3 6 8 5 7 9 4? Wie viele Vertauschungen haben hier maximal stattgefunden?! 2. Die maximale Anzahl an Vertauschungen ist gegeben durch die Anzahl Schlüssel im kleineren Bereich. 431 432

Analyse: Anzahl Vertauschungen Randomisiertes Quicksort Gedankenspiel Jeder Schlüssel aus dem kleineren Bereich zahlt bei einer Vertauschung eine Münze. Wenn ein Schlüssel eine Münze gezahlt hat, ist der Bereich, in dem er sich befindet maximal halb so gross wie zuvor. Jeder Schlüssel muss also maximal log n Münzen zahlen. Es gibt aber nur n Schlüssel. Folgerung: Es ergeben sich O(n log n) viele Schlüsselvertauschungen im schlechtesten Fall! Quicksort wird trotz Θ(n 2 ) Laufzeit im schlechtesten Fall oft eingesetzt. Grund: Quadratische Laufzeit unwahrscheinlich, sofern die Wahl des Pivots und die Vorsortierung nicht eine ungünstige Konstellation aufweisen. Vermeidung: Zufälliges Ziehen eines Pivots. Mit gleicher Wahrscheinlichkeit aus [l, r]. 433 434 Analyse (Randomisiertes Quicksort) Erwartete Anzahl verglichener Schlüssel bei Eingabe der Länge n: T (n) = (n 1) + 1 n n (T (k 1) + T (n k)), T (0) = T (1) = 0 k=1 Behauptung T (n) 4n log n. Beweis per Induktion: Induktionsanfang: klar für n = 0 (mit 0 log 0 := 0) und für n = 1. Hypothese: T (n) 4n log n für ein n. Induktionsschritt: (n 1 n) Analyse (Randomisiertes Quicksort) T (n) = n 1 + 2 n 1 T (k) H n 1 + 2 n 1 4k log k n n k=1 k=0 n/2 = n 1 + 4k log k }{{} log n 1 + n 1 k=n/2+1 k=0 4k log k }{{} log n n 1 + 8 n/2 n 1 (log n 1) k + log n k n k=1 k=n/2+1 = n 1 + 8 ( n(n 1) (log n) n ( n ) ) n 2 4 2 + 1 = 4n log n 4 log n 3 4n log n 435 436

Analyse (Randomisiertes Quicksort) Praktische Anmerkungen Theorem Im Mittel benötigt randomisiertes Quicksort O(n log n) Vergleiche. Rekursionstiefe im schlechtesten Fall: n 1 9. Dann auch Speicherplatzbedarf O(n). Kann vermieden werden: Rekursion nur auf dem kleineren Teil. Dann garantiert O(log n) Rekursionstiefe und Speicherplatzbedarf. 437 9 Stack-Overflow möglich! 438 Quicksort mit logarithmischem Speicherplatz Input : Array A der Länge n. 1 l r n. Output : Array A, sortiert zwischen l und r. while l < r do Wähle Pivot p A[l,..., r] k Partition(A[l,..., r], p) if k l < r k then Quicksort(A[l,..., k 1]) l k + 1 else Quicksort(A[k + 1,..., r]) r k 1 Praktische Anmerkungen Für den Pivot wird in der Praxis oft der Median von drei Elementen genommen. Beispiel: Median3(A[l], A[r], A[ l + r/2 ]). Es existiert eine Variante von Quicksort mit konstanten Speicherplatzbedarf. Idee: Zwischenspeichern des alten Pivots am Ort des neuen Pivots. Der im ursprünglichen Algorithmus verbleibende Aufruf an Quicksort(A[l,..., r]) geschieht iterativ (Tail Recursion ausgenutzt!): die If-Anweisung wurde zur While Anweisung. 439 440