Uebersicht Sortieralgorithmen • Einleitung • Heapsort Datenstrukturen & Algorithmen • Quicksort Matthias Zwicker Universität Bern Frühling 2009 2 Motivation Records und Keys • Sortieren ist Voraussetzung für viele Anwendungen • Datensatz besteht aus Menge von Records • Jeder Record enthält einen Key (Schlüssel) und zusätzliche Daten („Satellitendaten“) – Nach Bestellnummern sortierte Aufträge, etc. • Viele Algorithmen enthalten Sortierschritte • Daten werden anhand der Schlüssel sortiert – Suchen – GUIs (graphical user interfaces) • Zeichnen von grafischen Objekten die sich gegenseitig verdecken • Objekte sollen gemäss „liegt vor“ oder „liegt hinter“ Relation geordnet werden class Record { int key; SatelliteData data; } • In kommerzieller Datenverarbeitung wird mehr als 25% der Rechenzeit mit Sortieren verbracht class SatelliteData{ String name; String address; ... } 3 4 Uebersicht Ausgangslage Sortieralgorithmen • Sortiere Sequenz von ganzen Zahlen – Sortieren von Records mit Keys im Prinzip gleich • Einleitung • Heapsort • Eingabe: Zahlen <a1, a2, ..., an> • Quicksort • Ausgabe: Permutation <a <a´1, a a´2, ..., a a´n> so dass a´1 <= a´2, <= ... <= a´n • Beispiel – Eingabe: 8 2 4 9 3 6 – Ausgabe: 2 3 4 6 8 9 5 6 1 Heapsort Heaps • Suchverfahren mit Zeitkomplexität O(n lg n) • Felder mit einer zusätzlichen Struktur – Heap A – länge[A] Anzahl Elemente des Feldes – heap-grösse[A] Anzahl Elemente im Heap • In-place Verfahren – Speichert nur konstante Anzahl Elements ausserhalb des Eingabefeldes – Sortieren S ti d durch h Mi Mischen h (M (Merge SSort) t) iistt nicht i ht in-place! • Heap kann als Binärbaum angesehen werden – Jeder Knoten des Baumes entspricht einem Element d F des Feldes ld – Reihenfolge wie in Skizze 1 • Heap Datenstruktur zur Verwaltung der Daten heap-grösse[A] 2 länge[A] 4 3 5 6 8 Feld 7 9 10 Darstellung als Binärbaum Heaps Heap Eigenschaft • Wurzel A[1] • Max-Heap A[Vater(i)]>=A[i] • Berechnung der Indizes • Min-Heap A[Vater(i)]<=A[i] Vater[i] { return floor[i/2]; } Left[i] { return 2*i; } Right[i] { return 2*i+1; } h heap-grösse[A] ö [A] lä länge[A] [A] 1 heap-grösse[A] 2 länge[A] 4 1 2 3 4 5 6 7 8 9 101112 161410 8 7 9 3 2 4 1 x x 3 5 6 7 1 2 3 4 5 6 7 8 9 101112 Feld 4 8 8 2 Feld 8 7 1 2 3 4 5 6 7 8 9 101112 – Heaps auch nützlich in anderen Algorithmen – Prioritätswarteschlangen 2 14 1 16 5 7 6 9 3 10 8 7 3 9 10 4 1 Darstellung als Binärbaum 9 10 Darstellung als Binärbaum Max-Heap 9 10 Aufrechterhaltung der Heapeigenschaft Aufrechterhaltung der Heapeigenschaft • Ausgangslage • Max-Heapify(A,2) – Gegeben Index i – Bäume ausgehend von Left(i) und Right(i) sind Heaps – Knoten i verletzt Heapeigenschaft 4 14 8 2 2 4 1 16 5 7 1 6 9 3 10 2 7 3 9 10 8 1 4 8 3 5 6 7 9 10 1 2 4 8 11 3 5 6 7 9 10 12 2 Laufzeit Heap Konstruktion • Zugriff auf Knoten A[i], A[Left(i)] und A[Right(i)] in Θ(1) • „Bottom-up“ Max-Heapify • Durchlaufe alle Knoten (ausser Blätter) und führe auf jedem Max-Heapify aus • Von Kindern ausgehende Bäume haben höchstens 2n/3 Knoten • Lösung von T (n) ≤ T (2n/3) + Θ(1) mit Mastertheorem ergibt T (n) = O(lg n) 13 Heap Konstruktion Heap Konstruktion 1 2 3 4 5 6 7 8 9 10 4 1 3 2 16 9 1014 8 7 1 2 4 8 1 2 3 4 5 6 7 8 9 10 4 1 3 2 16 9 1014 8 7 1 6 7 9 10 4 8 3 5 8 4 14 7 8 2 1 2 3 5 6 9 10 1 2 4 1 2 3 5 14 6 9 10 7 4 8 6 4 5 16 9 10 8 7 3 5 2 1 3 10 6 9 4 9 10 8 7 3 4 8 3 5 6 7 9 10 1 2 7 2 3 5 6 7 9 10 15 Heap Sort 16 Heap Sort 1. Konstruiere Heap 2. Verschiebe grösstes Element im Heap an sortierte Position bis Heap leer 4 8 – Nach jeder Verschiebung Heap Eigenschaft aufrechterhalten 8 2 2 14 1 16 5 7 1 6 9 3 10 2 7 3 9 10 4 1 4 8 3 5 1 8 17 9 10 2 3 5 7 9 10 1 2 4 6 6 7 4 8 3 5 6 7 9 10 18 3 Heap Sort 2 8 4 4 8 10 Heap Sort 1 9 5 7 1 6 1 3 3 2 7 2 9 10 14 16 4 8 3 5 6 7 4 1 9 10 8 10 1 2 2 1 4 5 7 7 9 4 8 3 5 6 7 9 10 1 2 3 6 8 2 9 10 14 16 1 2 1 3 3 2 3 3 1 2 3 4 5 6 7 8 9 10 4 8 5 6 9 10 7 4 8 5 6 7 4 9 10 8 5 6 7 9 10 19 20 Aufwand Prioritätswarteschlangen • Heap Konstruktion • (Priority queues) • Aufrechterhaltung der Heap Eigenschaft • Datenstruktur zur Verwaltung einer Menge von Elementen, wobei jedes Element einen Schlüssel hat • Total • Operationen – Insert: Einfügen eines neuen Elements – Maximum: Abfragen des Elements mit grösstem (kleinstem) Schlüssel – Extract-Max: Entfernen des Elements mit grösstem (kleinsten) Schlüssel – Increase-Key: Verändern des Schlüssels eines Elements 21 Anwendungen 22 Implementation mit Heaps • Verwaltung von Arbeitsaufträgen geordnet nach Prioritäten (Zeitplanung, scheduling) – Rechenaufträge auf gemeinsam genutztem Rechner – Prozessverwaltung o essve waltu g in Multitasking Mult tas g • Implementation mit Heap Datenstruktur 23 24 4 Implementation mit Heaps Uebersicht Sortieralgorithmen • Einleitung • Heapsort • Quicksort 25 26 Quicksort Teile-und-beherrsche • Entwickelt von C. A. R. Hoare in 1962 • Sortiere ein Feld A mit n Elementen • Teile-und-beherrsche (divide-and-conquer) Schema 1. Teile: Zerlege Feld in zwei Teilfelder um ein Pivot q, so dass Elemente links von q <=A[q]<= Element rechts von q x ≤x x≤ 2. Beherrsche: Sortiere Teilfelder rekursiv • Sortiert „in-place“ • Beliebt in Praxis 3. Verbinde: Trivial • Schlüssel zum Erfolg: Zerlegung des Felds in linearer Zeit 27 Zerlegung des Felds 28 Zerlegung des Felds • Schleifeninvariante 29 30 5 Beispiel Beispiel p 6 10 13 5 8 3 2 11 6 i 10 3 j 13 8 r 3 2 11 31 Quicksort 32 Analyse • Annahme: keine doppelten Elemente – Alle Elemente sind verschieden • Aufruf Quicksort(A,1,länge[A]) 33 Worst case 34 Worst case • Rekursionsbaum • Eingabe ist sortiert • Zerlegung immer um grösstes oder kleinstes Element T (n) = T (0) + T (n − 1) + Θ(n) • Eine Seite der Zerlegung ist leer T (n) = T (0) + T (n − 1) + Θ(n) 35 36 6 Best case „Fast“ best case Rekursionsbaum • Nur für Intuition 1 9 T (n) = T ( 10 n) + T ( 10 n) + Θ(n) • Gleichmässige Zerlegung T (n) = 2T (n/2) + Θ(n) = Θ(n lg n) • Was wenn Zerlegung im Verhältnis 1 10 : 9 10 ? 1 T (n) = T ( 10 n) + T ( 109 n) + Θ(n) – Rekursionsbaum 37 38 Randomisierter Quicksort Analyse Idee: Zerlegung um ein zufälliges Element • Indikator Zufallsvariable ⎧ ⎨ • Laufzeit unabhängig von Eingabe Xk = ⎩ • Keine Annahmen über Eingabe nötig • Keine spezielle Eingabe führt zu Worst Case 1 0 if Partition generates a k : n − k − 1 split otherwise • Erwartungswert E[Xk ] = Pr{Xk = 1} = 1/n • Worst Case tritt auf bei „unglücklicher“ Folge von zufälligen Elementen 39 Analyse ⎧ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎨ T (n) = ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎩ = Erwartungswert E[T (n)] = E T (0) + T (n − 1) + Θ(n) if 0 : n − 1 split T (1) + T (n − 2) + Θ(n) if 1 : n − 2 split .. . T (n − 1) + T (0) + Θ(n) if n − 1 : 0 split Pn−1 k=0 Xk (T (k) 40 ⎡ ⎣ n−1 X k=0 ⎤ Xk (T (k) + T (n − k − 1) + Θ(n))⎦ + T (n − k − 1) + Θ(n)) 41 42 7 Rekursionsgleichung E[T (n)] = Substitutionsmethode X 2 n−1 E[T (k)] + Θ(n) n k=2 E[T (n)] = X 2 n−1 E[T (k)] + Θ(n) n k=2 • Beweise E[T [ ((n)] )] ≤ an lgg n für Konstante a > 0 • Benutze n−1 X 1 1 k lg k ≤ n2 lg n − n2 2 8 k=2 43 44 Quicksort Zusammenfassung Nächste Vorlesung • Einer der beliebtesten Sortieralgorithmen in der Praxis • Mehr Sortieren • Häufig ca. zwei Mal schneller als Merge Sort • Günstiges Verhalten mit Speicherhierarchien (Caches, virtueller Speicher) 45 46 8