Überblick Kap. 3: Sortieren (3) • Quick-Sort • Analyse von Quick-Sort • Quick-Sort Varianten Professor Dr. Petra Mutzel Lehrstuhl für Algorithm Engineering, LS11 Fakultät für Informatik, TU Dortmund 6. VO DAP2 SS 2009 Petra Mutzel • Heap-Sort 30. April 2009 DAP2 SS09 1 Petra Mutzel DAP2 SS09 Termine für Übungstests Motivation • 1. Übungstest: • Di 19. Mai, in der Vorlesung im AudiMax, Beginn: ab 12:15 Uhr, ab 12 Uhr anwesend sein wegen Sitzordnung „Warum soll ich hier bleiben?“ Wir lernen Quick-Sort „Was ist daran denn besonders?“ • 2. Übungstest: • Di 16. Juni, in der VO im AudiMax, Beginn: ab 12:15 Uhr, ab 12 Uhr anwesend sein wegen Sitzordnung Petra Mutzel DAP2 SS09 Quick-Sort gehört zu den „Top 10“ wichtigsten Algorithmen 3 Analyse von QuickSort: Average DAP2 SS09 4 • Teilt man sämtliche Folgen mit n Elementen mit dem Pivotelement (an der letzten Stelle), so erhält man sämtliche Folgen der Länge k-1 und n-k. – alle Schlüssel sind verschieden – o.B.d.A. A[i]∈{1,2,…n} – alle Permutationen sind gleich wahrscheinlich Rekursionsgleichung der Laufzeitfunktionen: • Jede Zahl k∈{1,2,…,n} tritt mit gleicher Wahrscheinlichkeit 1/n an Position n auf • Pivotelement k erzeugt zwei Folgen der Längen k-1 und n-k • Diese Folgen sind wieder zufällig: gilt DAP2 SS09 Petra Mutzel Analyse von QuickSort: Average • Grundannahmen Petra Mutzel 2 wobei die Summe über alle n möglichen Aufteilungen läuft und bn der Aufteilungsaufwand für eine Folge der Länge n ist. 5 Petra Mutzel DAP2 SS09 6 1 Analyse von QuickSort: Average Beweis von Average-Case Einsetzen von T(0)=0: • Wir zeigen: T(n)=O(n log n) • T(n)=Ω(n log n) ähnlich (o.Bw.) Lösung der Rekursionsgleichung: T(n)=Θ(n log n) Wir zeigen durch vollständige Induktion: es existieren c,n0>0, so dass für alle n≥n0: T(n) ≤ cn log n Wir wählen: n0=2. Induktionsanfang: n=2: T(2)=T(1)+bn=a+2b somit ist T(2)≤c2 log 2 g.d.w. c≥(a+2b)/2=a/2+b Petra Mutzel DAP2 SS09 7 Beweis von Average-Case ff Petra Mutzel DAP2 SS09 8 Eigenschaften von QuickSort Induktionsschluss: Sei nun n≥3, Beh. gilt für alle kleineren Werte: • Anzahl der Schlüsselvergleiche: Cbest(n)=Cavg(n)=Θ(n log n); Cworst(n)=Θ(n2) • Eigenschaften: – in situ? Θ(n) zusätzlichen Speicher – adaptiv? – stabil? Diese Ungleichung gilt, falls c≥4b Wähle insgesamt c=max {a/2+b,4b} Quicksort - Varianten • sehr gut in der Praxis • es existieren viele Varianten Randomisierter Quick-Sort Ziel: Laufzeit unabhängig von der „Qualität“ der Eingabefolge (vorsortiert, etc…) • Randomisierter Quicksort Idee: Wähle Pivotelement zufällig aus! • Quicksort mit log(n) Speicher Petra Mutzel Einfachste Umsetzung: „Neues“ Partitionieren: (1) z := Zufallszahl zwischen l und r (2) vertausche A[z] mit A[r] (3) normales Partitionieren DAP2 SS09 11 Petra Mutzel DAP2 SS09 12 2 Randomisierter Quick-Sort Quick-Sort mit log(n) Speicher Randomisierte Algorithmen: Es lassen sich keine Best-Case und Worst-Case Beispiele mehr konstruieren! Aber: Natürlich kann der Worst-Case noch eintreten! Bisher: O(n) Speicher l ... p-1 p p+1................ r Idee: Lange Teile sofort bearbeiten D.h.: Rekursiver Aufruf nur für kleinere Teile. diese Teile sind ≤ Hälfte der betrachteten Länge Tiefe der rekursiven Aufrufe: O(log n) Man berechnet eine Erwartete Laufzeit = Erwartungswert der Laufzeit ≈ durchschnittliche Laufzeit Average-Case E[ T(n) ] = O(n log n) Petra Mutzel DAP2 SS09 13 Petra Mutzel l ... p-1 p Idee: Lange Teile sofort bearbeiten bisher Zwischenschritt (1) procedure QS(ref A,l,r) (2) while l < r do { (3) p := Partition(A,l,r) (4) QuickSort(A,l,p-1) (5) l := p+1 (6) } Petra Mutzel DAP2 SS09 14 Quick-Sort mit log(n) Speicher Quick-Sort mit log(n) Speicher (1) procedure QS(ref A,l,r) (2) if l < r then { (3) p := Partition(A,l,r) (4) QuickSort(A,l,p-1) (5) QuickSort(A,p+1,r) (6) } DAP2 SS09 15 Was bisher geschah… Zwischenschritt (1) procedure QS(ref A,l,r) (2) while l < r do { (3) p := Partition(A,l,r) (4) QuickSort(A,l,p-1) (5) l := p+1 (6) } p+1................ r (1) procedure QS(ref A,l,r) (2) while l < r do { (3) p := Partition(A,l,r) (4) if p-l < r-p then { (5) QuickSort(A,l,p-1) (6) l := p+1 (7) } else { (8) QuickSort(A,p+1,r) (9) r := p-1 (10) } } Petra Mutzel DAP2 SS09 16 Übersicht Insertion-Sort: O(n2) einfach 2 Selection-Sort: Θ(n ) Merge-Sort: O(n log n) nicht in-situ Quick-Sort: praxis schnell O(n2) Heap-Sort Einführung in Datenstruktur Heap Analyse von Heap-Sort Jetzt: Heap-Sort: O(n log n) , in-situ Auf Basis von Selection-Sort! Petra Mutzel DAP2 SS09 17 Petra Mutzel DAP2 SS09 18 3 Selection-Sort… Heap (=Haufen) GUT In jedem Schritt wird ein Schlüssel an seine richtige Position gesetzt Heap: eine neue Datenstruktur! Speicherung… SCHLECHT …weiterhin als Array (in-situ!) Suchen des richtigen Schlüssels: Θ(n) Interpretation… IDEE Den unsortierten Teil „vorsortieren” Schnelles Finden des nächsten Schlüssels Petra Mutzel …als binärer Baum, an dessen Wurzel immer das größte Element stehen soll DAP2 SS09 19 Petra Mutzel Definition Heap 12345678 F=<8,6,7,3,4,5,2,1> Ähnlich sind Min-Heaps definiert. Dort gilt: Falls 2i≤n, so gilt ki≤k2i und falls 2i+1≤n so gilt ki≤k2i+1. Petra Mutzel DAP2 SS09 F=<8,6,7,3,4,5,2,1> 1 Heap-Eigenschaft: Falls 2i≤n, so gilt ki≥k2i und falls 2i+1≤n so gilt ki≥k2i+1. Heap–Eigenschaft: Schlüssel der Elternknoten ist größer gleich denen seiner Kinder 21 Heap: Interpretation 2 6 3 3 8 5 4 7 6 5 7 2 1 Petra Mutzel S 8 4 Binärer Baum 1 20 Heap: Interpretation Eine Folge H=<k1,k2,…,kn> von Schlüsseln ist ein (Max-) Heap, wenn für jede Position i die folgende Heap-Eigenschaft erfüllt ist: Falls 2i≤n, so gilt ki≥k2i und falls 2i+1≤n so gilt ki≥k2i+1. Beispiel: DAP2 SS09 DAP2 SS09 22 Wurzel Ebene 1 1 S Interpretation als Binärer Baum 2 O 3 Ebene 2 R Knoten 2 O 3 Elter / Vater R Kind = Einträge im Baum 4 T 5 I 6 N 7 G Ebene 3 4 T Kanten verbinden Knoten 1 Speicherung als Array 2 3 4 S O R T 5 6 7 I N G 5 I 6 N 7 G Blätter = Knoten ohne Kinder Binärer Baum: maximal 2 Kinder pro Knoten 4 Tiefe/Höhe des Baums Ebene 1 2 Ebene 2 1 2 4 Ebene 3 4 T 15 8 Ebene 4 2k-1 2k-1 Ebene k 7 S 1 O 5 3 I 6 R N 7 G Heap-Eigenschaft Heap–Eigenschaft: Schlüssel der Elternknoten ist größer gleich denen seiner Kinder 1 2 Ebene 1 Tiefe/Höhe eines 1 S Baums = Anzahl der Ebenen - 1 2 Ebene 2 Gegebene Höhe h: 3 R 2 O nmax = 2h+1-1 nmin = 2h 4 Maximale Höhe bei n Ebene 3 4Elementen? 6 N T 5 I 15 8 Ebene 4 2k-1 2k-1 Ebene k 7 7 G n = 2h hmax = log2 n Höhe des Heaps: O(log n) Elemente im unsortierten Array so verschieben, dass die Heap-Eigenschaft erfüllt ist (CreateHeap) S O 3 R Größtes Element im Heap finden ist einfach Wurzel = erstes Element im Array ∀ Indizes i: 4 T 5 I 6 N 7 G Wurzel aus Heap entfernen Heap-Eigenschaften wiederherstellen (Sifting) nicht erfüllt! falls diese Indizes existieren 1 2 3 4 S O R T 5 6 7 I N G Petra Mutzel CreateHeap DAP2 SS09 29 CreateHeap Beobachtung Die Heapbedingung ist an den Blättern erfüllt. 1 2 Algorithmus Betrachte Knoten über den Blättern repariere Teilheap Bearbeite Baum von unten nach oben Teilbäume sind immer Heaps 1 Idee von Heap-Sort Array A[1…n] A[i] ≥ A[2i] und A[i] ≥ A[2i+1] 3 # Knoten PRO Ebene 1 # Knoten BIS Ebene 3 # Knoten PRO Ebene # Knoten BIS Ebene 1 Tiefe/Höhe des Baums procedure CREATEHEAP () { for i := n/2 … 1 { SIFTDOWN (i, n) } } S O 3 R 1 S i 2 O procedure SIFTDOWN (i, m) { while Knoten i hat Kinder ≤ m { j := Kind ≤ m mit größerem Wert 5 I 6 4 T if A[i] < A[j] then { vertausche A[i] und A[j] 1 2 3 4 i := j S O R T } else return } } 3 R 4 T 1 5 I 2 3 6 4 S O R T Petra Mutzel N 5 7 6 G 7 I N G DAP2 SS09 30 N 7 2i 5 G 2i+1 6 7 I N G 5 CreateHeap CreateHeap procedure CREATEHEAP () { for i := n/2 … 1 { SIFTDOWN (i, n) } } 1 Heap-Erstellung beendet i procedure CREATEHEAP () { for i := n/2 … 1 { SIFTDOWN (i, n) } } S i 2 O procedure SIFTDOWN (i, m) { 3 R while Knoten i hat Kinder ≤ m { j := Kind ≤ m mit größerem Wert 5 I 6 N 7 G 4 T if A[i] < A[j] then { 2i 2i+1 vertausche A[i] und A[j] 1 2 3 4 5 6 7 i := j S O R T I N G } else return } } 1 S j 2 T procedure SIFTDOWN (i, m) { 3 R while Knoten i hat Kinder ≤ m { j := Kind ≤ m mit größerem Wert 5 I 6 N 7 G 4 O if A[i] < A[j] then { vertausche A[i] und A[j] 1 2 3 4 5 6 7 i := j S T R O I N G } else return } } HeapSort HeapSort procedure HEAPSORT () { CREATEHEAP () for k := n … 2 { vertausche A[1] und A[k] SIFTDOWN (1, k-1) } } 1 2 4 S 3 O 5 I 1 2 3 procedure HEAPSORT () { CREATEHEAP () for k := n … 2 { vertausche A[1] und A[k] SIFTDOWN (1, k-1) } } G T 6 4 R N 5 7 6 k G T 1 4 7 G T S R O I N G T Petra Mutzel DAP2 SS09 2 O G S G O 5 I 1 2 3 G S 3 6 4 R N 5 7 6 k T 7 G S O G S R G O I N T 34 HeapSort Petra Mutzel DAP2 SS09 35 HeapSort procedure HEAPSORT () { CREATEHEAP () for k := n … 2 { vertausche A[1] und A[k] SIFTDOWN (1, k-1) } } 1 4 2 O G 5 I 1 2 3 procedure HEAPSORT () { CREATEHEAP () for k := n … 2 { vertausche A[1] und A[k] SIFTDOWN (1, k-1) } } N R S 3 6 4 R N k N S 5 7 6 T 4 7 N R S O N R G I N S T Petra Mutzel DAP2 SS09 1 2 O I G 5 k RI 1 2 3 O R I 3 6 4 N S 5 7 6 T 7 O R I O I N G R I S T 36 Petra Mutzel DAP2 SS09 37 6 HeapSort HeapSort procedure HEAPSORT () { CREATEHEAP () for k := n … 2 { vertausche A[1] und A[k] SIFTDOWN (1, k-1) } } 1 2 4 I 3 k O G 5 R 1 2 3 procedure HEAPSORT () { CREATEHEAP () for k := n … 2 { vertausche A[1] und A[k] SIFTDOWN (1, k-1) } } O G N 6 4 G N S 5 7 6 T 4 7 O G N I G N O G R S T Petra Mutzel DAP2 SS09 1 2 G I O 5 R 1 2 3 G N I 3 6 4 k G N S 5 7 6 T 7 G N I G I G N O R S T 38 Petra Mutzel DAP2 SS09 39 HeapSort procedure HEAPSORT () { CREATEHEAP () for k := n … 2 { vertausche A[1] und A[k] SIFTDOWN (1, k-1) } } 1 4 2 k G I O 5 R 1 2 3 G I 3 6 4 N S 5 7 6 T 7 G I G I N O R S T Petra Mutzel DAP2 SS09 40 7