Grundlagen der Programmierung 2 Sortierverfahren Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 30. Mai 2006 Sortieren Ziel: Bringe Folge von Objekten in eine Reihenfolge unsortiert: (“Müller“, “Darmstadt“, 456) (“Meier“, “Wiesbaden“,123 ) (“Schmitt“, “Frankfurt“, 789) (“Adam“, “Hamburg“, 999) Aufsteigend nach Namen sortiert: (“Adam“, “Hamburg“, 999) (“Meier“, “Wiesbaden“, 456) (“Müller“, “Darmstadt“, 123) (“Schmitt“, “Frankfurt“, 789) Sortierschüssel: Namen. Grundlagen der Programmierung 2 - 2 - Sortieren, Beispiel (2) Aufsteigend nach Kundennummer sortiert: (“Müller“, “Darmstadt“, 123) (“Meier“, “Wiesbaden“, 456) (“Schmitt“, “Frankfurt“, 789) (“Adam“, “Hamburg“, 999) Sortierschüssel: Kundennr. Grundlagen der Programmierung 2 - 3 - Sortieren Eingabe: Ausgabe: Annahme: Liste von Objekten Vergleichsoperator ≤ auf den Objekten Liste der Objekte mit i.a. anderer Reihenfolge [a1, . . . an] so dass i ≤ j ⇒ ai ≤ aj Ordnung ist transitiv, reflexiv, total, aber nicht notwendig antisymmetrisch ≤ ist total :⇔ es gilt a ≤ b oder b ≤ a. Grundlagen der Programmierung 2 - 4 - Sortiermethoden Annahme im Folgenden: Liste von Zahlen. Wir betrachten: Insert-Sort Bubble-Sort Merge-Sort Quick-Sort Sortieren Sortieren Sortieren Sortieren durch durch durch durch Einfügen binäres Vertauschen rekursives Mischen rekursive Zerlegung und Vergleichen Es gibt noch weitere Sortierverfahren Grundlagen der Programmierung 2 - 5 - Sortieren • Sortierprogramme in Haskell für Listen Demonstration der Prinzipien Abschätzung der Komplexität • Sortierprogramme in Python/Java für Arrays Prinzipien der destruktiven Abänderung In-place-Algorithmen (siehe Demo) Grundlagen der Programmierung 2 - 6 - Sortierprogramme in imperativen miersprachen, Speicherverwaltung Program- Zusätzlicher Aspekt: effiziente Speicherverwaltung Falls Sortierung innerhalb des Eingabe-Arrays: In-Place- Verfahren. Insertion-Sort, Bubble-Sort, Quick-Sort: In-Place-Verfahren Merge-Sort: Es gibt ein effizientes In-Place-Merge-Verfahren, der Algorithmus ist nicht so offensichtlich zu finden. Grundlagen der Programmierung 2 - 7 - Sortieren durch Einfügen (Insert-Sort) Idee: geordnetes Einfügen der Elemente in die bereits sortierte Liste Sortiere: 5,3,99,1,2,7 sortierte Liste 5 3,5 3,5, 99 1,3,5, 99 1,2,3,5, 99 1,2,3,5, 7, 99 restliche Elemente 3,99,1,2,7 99,1,2,7 1,2,7 2,7 7 Grundlagen der Programmierung 2 - 8 - Sortieren mit Bubblesort Vertauschung von benachbarten Elementen; falls notwendig: Mehrfaches Durcharbeiten der Liste 5 3 5 3 5 3 5 3 5 1 1 5 1 5 1 5 1 5 1 5 1 2 ... 99 99 99 1 3 3 3 3 3 2 5 1 1 1 99 99 99 99 99 2 3 3 2 2 2 2 2 2 2 2 99 99 99 Grundlagen der Programmierung 2 7 7 7 7 7 7 7 7 7 7 7 - 9 - Quicksort: Rekursives Zerlegen Idee Pivot = erstes Element der Liste: • Zerlege Liste in Teillisten von Elemente, die bzgl Pivot: kleinere, grössere und gleiche Elemente enthalten • Sortiere diese rekursiv (Quicksort) • Füge sie zusammen. Grundlagen der Programmierung 2 - 10 - Quicksort: Beispiel Sortiere: 5,3,99,1,2,7 Pivot kleinere/größere Elte Pivots kleinere/größere Elte Pivots kleinere/größere Elte Zusammensetzen: Grundlagen der Programmierung 2 5 3,1,2 99,7 1 | 99 2,3 | 7 2 | 3 | 1,2,3,5,7,99 - 11 - Sortieren mit Quicksort: Haskell-Programm quicks quicks quicks quicks [] [x] [x,y] (x:xs) = = = = [] [x] if x <= y then [x,y] else [y,x] let (llt,lge) = splitlist x xs in (quicks llt) ++ (x: (quicks lge)) splitlist x y = splitlistr x y [] [] splitlistr x [] llt lge = (llt,lge) splitlistr x (y:ys) llt lge = if y < x then splitlistr x ys (y: llt) lge else splitlistr x ys llt (y:lge) Grundlagen der Programmierung 2 - 12 - Mergesort: Sortieren durch Mischen Rekursives Verfahren: Zerlege Liste in erste und zweite Hälfte sortiere beide rekursiv zusammenmischen Sortiere: 5,3,99,1,2,7 Zerlegen Zerlegen ... Merge Merge 5,3,99 | 1,2,7 5 3,99 | 1 2,7 ... | ... 5 3,99 | 1 2,7 3,5,99 | 1,2,7 1,2,3,5,7,99 Grundlagen der Programmierung 2 - 13 - Sortieren: Mindestanzahl der Vergleiche Satz Sortieren einer Liste von n Zahlen durch Vergleichsoperationen benötigt im schlechtesten Fall mindestens n ∗ log2(n) Vergleiche. Begründung: Ein Entscheidungsbaum hat n! Blätter, da jede Eingabereihenfolge möglich ist. Die Tiefe d des Baumes > log2(n!). Offenbar: n! ≥ 1 . . ∗ 1} ∗ n/2 ∗ . . . ∗ n/2 = (n/2)(n/2). | ∗ .{z n/2 | {z n/2 } log2(n!) > log((n/2)(n/2)) = 0.5 ∗ n ∗ log(n/2) = 0.5 ∗ n ∗ (log2(n) − 1). D.h. Ω(n ∗ log2(n)). Grundlagen der Programmierung 2 - 14 - Eigenschaften der Sortierverfahren Kriterien: • Zeitbedarf im schlechtesten Fall / besten Fall / im Mittel • Stabilität Ein Sortierverfahren nennt man stabil, wenn die Reihenfolge von Elementen mit gleichem Sortierschlüssel erhalten bleibt. Grundlagen der Programmierung 2 - 15 - Eigenschaften des Insert-Sort Gut für kleinere Listen, oder fast sortierte Listen im schlechtesten Fall: O(n2): Für Listen der Länge n höchstens: 1 + 2 + . . . + (n − 1) Vergleiche im besten Fall: O(n) für vorsortierte Listen. Die Haskell-Implementierung ist stabil. Grundlagen der Programmierung 2 - 16 - Eigenschaften des Bubble-Sort Gut: wenn Elemente schon in der Nähe ihres endgültigen Platzes sind. im schlechtesten Fall: (n − 1) + (n − 2) + . . . + 1 = O(n2) im besten Fall: O(n), wenn Liste schon sortiert Stabil, wenn gleiche Elemente nicht vertauscht werden. Grundlagen der Programmierung 2 - 17 - Eigenschaften des Quicksort im schlechtesten Fall: im besten Fall: Im Mittel: Gut: O(n2), wenn Liste bereits sortiert bzw. bei ungünstiger Reihenfolge (beim In-Place-Ve O(n ∗ log(n)) O(n ∗ log(n)) wenn Listen groß und Werte zufällig verteilt. Mit zufällig erzeugten Listen ist es das beste Verfahren Haskell-Implementierung ist stabil, Grundlagen der Programmierung 2 - 18 - Eigenschaften des Mischsort im schlechtesten Fall: Im besten Fall: Gut: O(n ∗ log(n)). auch O(n ∗ log(n)). Wenn keine Komplexitäts-Ausrutscher vorkommen sollen Stabil, wenn der Merge Stabilität beachtet: D.h. wenn gleiche Elemente aus der linken Liste vor denen aus der rechten Liste einsortiert werden. Grundlagen der Programmierung 2 - 19 -