Datenstrukturen und Algorithmen VO 708.031 11.11.2010 [email protected] 1 Wiederholung • QuickSort: – Sortieralgorithmus nach Divide-and-Conquer Prinzip (rekursives Zerlegen von Feldern) – Laufzeit hängt von Teilungsindex k ab (ist durch Pivotelement bestimmt) T(n) = T(k) + T(n-k) + O(n) • Bester Fall: k=n/2 ⇒ T(n) = O(n*log n) • Schlechtester Fall: k=1 ⇒ T(n) = O(n2) • Mittlerer Fall: P(k)=1/(n-1) ⇒ T(n) = O(n*log n) Randomisierte Pivotwahl 11.11.2010 [email protected] 2 Untere Schranke für Sortieren • Die bisher betrachteten schnellen Sortieralgorithmen (MergeSort, HeapSort, QuickSort) brauchen O(n*log n) Zeit • Gibt es einen schnelleren Sortieralgorithmus? • Wir zeigen: Jedes Sortierverfahren, das mittels Vergleichen arbeitet, braucht mindestens c⋅n⋅log n Vergleiche im worst case 11.11.2010 [email protected] 3 Untere Schranke für Sortieren • Der Kontrollfluss von vergleichsbasierten Sortierverfahren kann als Entscheidungsbaum dargestellt werden: Beispiel: drei Zahlen a1, a2, a3: alle möglichen Programmverzweigungen Innere Knoten: Vergleiche zwischen Elementen Blätter: Sortierte Reihenfolge des Inputs ⇒ Es gibt n! Blätter Ast: Kontrollfluss für best. Input 11.11.2010 [email protected] 4 Untere Schranke für Sortieren • Das worst-case Verhalten des Algorithmus entspricht dem längsten Ast im Entscheidungsbaum (# Knoten = # Vergleiche) • Der längste Ast wird kürzestmöglich, wenn alle Äste ungefähr gleich lang sind • Idealer Algorithmus entspricht einem vollständigen Binärbaum mit n! Blättern 11.11.2010 [email protected] 5 Untere Schranke für Sortieren • Die Höhe eines Binärbaums mit n! Blättern ist Ω(n*log n) • ⇒ Ω(n*log n) ist eine untere Schranke für die Anzahl der im worst case zum Sortieren notwendigen Vergleiche • ⇒ Die worst case Laufzeit vergleichsorientierter Sortierverfahren ist Ω(n*log n) • MergeSort und HeapSort sind worst-case optimal 11.11.2010 [email protected] 6 RadixSort • Beispiel für einen nicht vergleichsorientierten Sortieralgorithmus Sortieren von n Dezimalzahlen der Länge d: RADIXSORT (A, d) 1: FOR i = 1 TO d 2: Ordne A nach i-ter Ziffer v.h. in Fächer ein (Streuphase) 3: Fasse die Fächer in aufsteigender Reihenfolge wieder in A zusammen (Sammelphase) T(n) = O(d*n) … linear, wenn d als konstant betrachtet wird! • Nach den ersten k Durchläufen sind die Zahlen, eingeschränkt auf die letzten k Ziffern, sortiert • Wichtig: Die vorige Reihenfolge innerhalb der Fächer muss aufrechterhalten werden 11.11.2010 [email protected] 7 Eigenschaften von Sortierverfahren • Ein Sortierverfahren ist… – stabil: Elemente mit identischen Sortierschlüsseln erscheinen in Input und Output in gleicher Reihenfolge – adaptiv: (teilweise) vorsortierte Folgen werden effizienter sortiert (besseres Laufzeitverhalten für „fast“ sortierte Folgen) – worst-case optimal: Jede Eingabefolge wird in O(n*log n) Zeit sortiert (der unteren Schranke für vergleichsbasierte Sortierverfahren) – in-place: außer für einzelne Variablen (i, j, …) wird kein Zusatzspeicher (Hilfsfelder, …) benötigt 11.11.2010 [email protected] 8 Vergleich von Sortierverfahren 11.11.2010 [email protected] 9 Finden der i-kleinsten Zahl • Erste Idee: Sortieren, A[i] nehmen – T(n) = O(n*log n) + O(1) = O(n*log n) • Spezialfälle: i=1 (Minimum), i=n (Maximum) – n-1 Vergleiche ⇒ T(n) = O(n) • Minimum und Maximum gleichzeitig: – Vergleiche pro Paar nur die kleinere (größere) Zahl mit dem Minimum (Maximum) ⇒ 3n/2 < 2(n-1) Vergleiche 12.11.2009 [email protected] 10 Finden der i-kleinsten Zahl • Mittels Zerlegen von Feldern (PARTITION): Ist i≤k, dann suche weiter in A[1..k], sonst suche die (i-k)kleinste Zahl in A[k+1..n] SELECT(A, l, r, i) 1: IF l = r THEN RETURN A[l] 2: k = PARTITION (A, l, r) 3: x = k-l+1 4: IF i ≤ x THEN SELECT(A, l, k, i) 5: ELSE SELECT(A, k+1, r, i-x) x … Anzahl der kleineren Elemente im betrachteten Bereich A[l..r] T(n) ≤ T(max{k, n-k}) + O(n) i-kleinste Zahl kann in größere Hälfte fallen 12.11.2009 [email protected] PARTITION 11 Finden der i-kleinsten Zahl • Mittels Zerlegen von Feldern (PARTITION): – Laufzeit hängt davon ab, wie gut A zerlegt wird – Bester Fall: k=n/2 ⇒ T(n) = O(n) – Schlechtester Fall: k=1 (k=n-1), ⇒ T(n) = O(n2) – Mittlerer Fall: mit randomisierter Pivotwahl ⇒ T(n) = O(n) 12.11.2009 [email protected] 12 Finden der i-kleinsten Zahl • Durch deterministische Wahl (Berechnung) des Pivotelementes kann O(n) Zeit im worst case erreicht werden! • Pivotwahl: – Teile A[1..n] in Gruppen zu je 5 Elementen: A[1..5], A[6..10], ... – Bestimme für jeden dieser n/5 Gruppen ihren Median O(1) Zeit pro Gruppe ⇒ O(n) Zeit – Rufe SELECT rekursiv auf, um den Median dieser n/5 Zahlen zu bestimmen (i=⌊n/2⌋) – Dieser Median ist das Pivotelement h für PARTITION 12.11.2009 [email protected] 13 Finden der i-kleinsten Zahl • Beispiel: (http://en.wikipedia.org/wiki/Selection_algorithm) Mediane: Rot: Median der Mediane = Pivotelement h; Grau: Zahl < h • Beobachtung: Mindestens 3n/10 Elemente sind größer (kleiner) als h – Die Hälfte der n/5 Gruppen hat jeweils mindestens 3 Zahlen größer (kleiner) als h 11.11.2010 [email protected] 14 Finden der i-kleinsten Zahl • Im schlimmsten Fall muss die Suche auf 7n/10 Elementen fortgesetzt werden • Laufzeit von SELECT: Restl. Elemente Lokale Mediane Median der Mediane • Man kann zeigen: T(n) = O(n) 11.11.2010 [email protected] 15 Danke für Ihre Aufmerksamkeit! Bis zum nächsten Mal. (Donnerstag, 18. Nov. 2010, 11:15, i13) 11.11.2010 [email protected] 16