Heapsort, Quicksort, Mergesort. 8. Sortieren II

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

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

Abschnitt: Algorithmendesign und Laufzeitanalyse

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

Kapitel 6 Elementare Sortieralgorithmen

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

Algorithmen und Datenstrukturen

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

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

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

Übung Algorithmen I

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen Heapsort

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

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.

Tutoraufgabe 1 (Sortieralgorithmus):

Algorithmen und Datenstrukturen

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

Algorithmen und Datenstrukturen

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

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

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

Kapitel 8 Fortgeschrittene Sortieralgorithmen

7. Sortieren Lernziele. 7. Sortieren

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

4. Sortieren 4.1 Vorbemerkungen

2. Effizienz von Algorithmen

13. Binäre Suchbäume

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

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

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

Quicksort ist ein Divide-and-Conquer-Verfahren.

Programmiertechnik II

Algorithmen und Datenstrukturen

Suchen und Sortieren Sortieren. Heaps

Übung: Algorithmen und Datenstrukturen SS 2007

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

Kap. 3: Sortieren. Überblick. Unser Sortierproblem. Motivation. Laufzeitmessung. Warum soll ich hier bleiben? Sortierverfahren sind WICHTIG!!!

Algorithmen und Datenstrukturen SS09. Foliensatz 15. Michael Brinkmeier. Technische Universität Ilmenau Institut für Theoretische Informatik

Datenstrukturen und Algorithmen. 7. Suchen in linearen Feldern

Wir wollen nun die Behauptung beweisen, dass die Laufzeit von SELECT linear ist, also dass T (n) = O(n) gilt.

f 1 (n) = log(n) + n 2 n 5 f 2 (n) = n 3 + n 2 f 3 (n) = log(n 2 ) f 4 (n) = n n f 5 (n) = (log(n)) 2

Algorithmen und Datenstrukturen Wintersemester 2004/ November T(n) = T(n a) + T(a) + n

Sortieralgorithmen. Selection Sort

Übung Algorithmen und Datenstrukturen

Informatik II Prüfungsvorbereitungskurs

Termine für Übungstests. Kap. 3 Sortieren HeapSort ff Priority Queues. Motivation. Überblick. Analyse SiftDown

Build-Max-Heap. Build-Max-HeappAq. Satz Nach Ablauf von Build-Max-Heap ist A ein Heap. Build-Max-Heap hat Laufzeit Opnq.

Beispiellösungen zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 6

Alle bislang betrachteten Sortieralgorithmen hatten (worst-case) Laufzeit Ω(nlog(n)).

Erster Sortier-Algorithmus: Bubblesort

Klausur Algorithmen und Datenstrukturen SS August Arbeitszeit 90 min

Algorithmen und Datenstrukturen 1-3. Seminar -

Vorlesung Datenstrukturen

Übung Algorithmen I

Übung Algorithmen und Datenstrukturen

lim log 2n n = > 0 Da es einen Limes gibt, gibt es auch einen Limes inferior, der gleich diesem Limes ist.

Algorithmen und Datenstrukturen

2 Sortieren. Beispiel: Es seien n = 8 und a = i : a i : ϕ(i) : a ϕ(i) :

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

Sortieren und Suchen. Kapitel II. Sortieren und Suchen

Algorithmen und Datenstrukturen

damit hätten wir nach Ende der Schleife: "a[0 n-1] enthält nur Elemente aus a[0 n-1], aber in sortierter Reihenfolge".

11. Elementare Datenstrukturen

Algorithmen und Datenstrukturen (Th. Ottmann und P. Widmayer) Folien: Suchverfahren Autor: Stefan Edelkamp / Sven Schuierer

Suchen und Sortieren

Kapitel 4: Dynamische Datenstrukturen. Algorithmen und Datenstrukturen WS 2012/13. Prof. Dr. Sándor Fekete

Informatik II Vorlesung am D-BAUG der ETH Zürich

2.3.1 Einleitung Einfache Sortierverfahren Höhere Sortierverfahren Komplexität von Sortierverfahren Spezielle Sortierverfahren

Counting - Sort [ [ ] [ [ ] 1. SS 2008 Datenstrukturen und Algorithmen Sortieren in linearer Zeit

Vorlesung Datenstrukturen

Kapitel 2. Sortieren. Adressenverwaltung (lexikographisch) Treerlisten bei Suchanfragen (Relevanz) Verdeckung (z-koordinate) ...

Kurs 1663 Datenstrukturen" Musterlösungen zur Klausur vom Seite 1. Musterlösungen zur Hauptklausur Kurs 1663 Datenstrukturen 15.

Dies ist gerade der konstruktive Schritt beim Aufbau von Binomialbäumen.

JAVA - Suchen - Sortieren

> Parallele Systeme Übung: 4. Übungsblatt Philipp Kegel Wintersemester 2012/2013. Parallele und Verteilte Systeme, Institut für Informatik

Algorithmen und Datenstrukturen 1

Sortieralgorithmen. Direkte Sortierverfahren & Shellsort, Quicksort, Heapsort. Vorlesung Algorithmen und Datenstrukturen 2 im SS 2004

Informatik II. Vorlesung am D-BAUG der ETH Zürich. Felix Friedrich & Hermann Lehner FS 2018

Asymptotische Laufzeitanalyse: Beispiel

Musterlösungen zu Datenstrukturen und Algorithmen SS 2005 Blatt 2, Aufgabe 3 Wir schreiben zunächst alle Funktionen zur Basis 2.

Algorithmen und Datenstrukturen 1

2.2 Allgemeine (vergleichsbasierte) Sortierverfahren

Datenstruktur, die viele Operationen dynamischer Mengen unterstützt

Informatik II, SS 2014

7. Übung zu Algorithmen I 1. Juni 2016

Informatik II. 1. Einführung. Ziele der Vorlesung. Inhalte der Vorlesung. Vorlesung am D-BAUG der ETH Zürich

Binäre Suchbäume. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

Informatik II, SS 2014

Technische Universität Wien Institut für Computergraphik und Algorithmen Arbeitsbereich für Algorithmen und Datenstrukturen

Programmieren I. Kapitel 7. Sortieren und Suchen

Denition: Rang eines Elements e einer Folge s = Position von e in sort(s) (angefangen bei 1). Frage: warum ist r nicht notwendig eindeutig?

Pro Informatik 2009: Objektorientierte Programmierung Tag 17. Marco Block-Berlitz, Miao Wang Freie Universität Berlin, Institut für Informatik

Bucketsort. Korrektheit. Beispiel. Eingabe: Array A mit n Elementen im Bereich [0,1) Annahme: die Elemente sind in [0,1) gleichverteilt.

NAME, VORNAME: Studiennummer: Matrikel:

Grundzüge DS & Alg (WS14/15) Lösungsvorschlag zu Aufgabenblatt 3. Aufgabe 1. (a) nicht-heap (b) Heap 25. (c) Beinahe-Heap 9.

11.1 Grundlagen - Denitionen

Humboldt-Universität zu Berlin Berlin, den Institut für Informatik

Transkript:

209 Heapsort, Quicksort, Mergesort 8. Sortieren II

210 8.1 Heapsort [Ottman/Widmayer, Kap. 2.3, Cormen et al, Kap. 6]

211 Heapsort Inspiration von Selectsort: Schnelles Einfügen Inspiration von Insertionsort: Schnelles Finden der Position? Können wir das beste der beiden Welten haben?! Ja, aber nicht ganz so einfach...

212 [Max-]Heap 6 Binärer Baum mit folgenden Eigenschaften 1 vollständig, bis auf die letzte Ebene Wurzel 22 2 Lücken des Baumes in der letzten Ebene höchstens rechts. 16 20 12 15 18 17 Vater Kind 3 Heap-Bedingung: Max-(Min-)Heap: Schlüssel eines Kindes kleiner (grösser) als der des Vaters 3 2 8 11 14 Blätter 6 Heap (Datenstruktur), nicht: wie in Heap und Stack (Speicherallokation)

Heap und Array Baum Array: 22 1 Kinder(i) = {2i, 2i + 1} Vater(i) = i/2 20 2 18 3 Vater 16 4 12 5 15 6 Kinder 17 7 3 8 2 9 8 10 11 11 Abhängig von Startindex! 7 14 12 22 [1] 20 18 [2] [3] 16 12 15 17 [4] [5] [6] [7] 3 2 8 11 14 [8] [9] [10] [11] [12] 7 Für Arrays, die bei 0 beginnen: {2i, 2i + 1} {2i + 1, 2i + 2}, i/2 (i 1)/2 213

Rekursive Heap-Struktur 214 Ein Heap besteht aus zwei Teilheaps: 22 20 18 16 12 15 17 3 2 8 11 14

215 Einfügen 22 20 18 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 22 20 16 12 18 21 17 17 3 2 8 11 14 15

216 Maximum entfernen 21 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) 20 18 16 12 15 17 3 2 8 11 14 20 16 18 14 12 15 17 3 2 8 11

Algorithmus Versickern(A, i, m) 217 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

218 Heap Sortieren 7 6 4 5 1 2 A[1,..., n] ist Heap. Solange n > 1 swap(a[1], A[n]) Versickere(A, 1, n 1); n n 1 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

Heap erstellen 219 Beobachtung: Jedes Blatt eines Heaps ist für sich schon ein korrekter Heap. Folgerung: Induktion von unten!

Algorithmus HeapSort(A, n) 220 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.

Analyse: Sortieren eines Heaps 221 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 222 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: v(n) O(n). h 2 h)

223 8.2 Mergesort [Ottman/Widmayer, Kap. 2.4, Cormen et al, Kap. 2.3],

Zwischenstand 224 Heapsort: O(n log n) Vergleiche und Bewegungen.? Nachteile von Heapsort?! Wenig Lokalität: per Definition springt Heapsort im sortierten Array umher (Negativer Cache Effekt).! Zwei Vergleiche vor jeder benötigten Bewegung.

225 Mergesort (Sortieren durch Verschmelzen) 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).

Merge 226 1 4 7 9 16 2 3 10 11 12 1 2 3 4 7 9 10 11 12 16

Algorithmus Merge(A, l, m, r) 227 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]

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. 228

Analyse (Merge) 229 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).

Mergesort 230 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

Algorithmus Rekursives 2-Wege Mergesort(A, l, r) 231 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

Analyse 232 Rekursionsgleichung für die Anzahl Vergleiche und Schlüsselbewegungen: n n C(n) = C( ) + C( ) + Θ(n) Θ(n log n) 2 2

Algorithmus StraightMergesort(A) 233 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

Analyse 234 Wie rekursives Mergesort führt reines 2-Wege-Mergesort immer Θ(n log n) viele Schlüsselvergleiche und -bewegungen aus.

Natürliches 2-Wege Mergesort 235 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.

Natürliches 2-Wege Mergesort 236 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

Algorithmus NaturalMergesort(A) 237 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

Analyse 238 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. Natürliches Mergesort führt im schlechtesten und durchschnittlichen Fall Θ(n log n) viele Vergleiche und Bewegungen aus.

239 8.3 Quicksort [Ottman/Widmayer, Kap. 2.2, Cormen et al, Kap. 7]

240 Quicksort? 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!

Quicksort (willkürlicher Pivot) 241 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

Algorithmus Quicksort(A[l,..., r] 242 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])

Zur Erinnerung: Algorithmus Partition(A[l,..., r], p) 243 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

Analyse: Anzahl Vergleiche 244 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 )

Analyse: Anzahl Vertauschungen 245 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.

246 Analyse: Anzahl Vertauschungen 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!

Randomisiertes Quicksort 247 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].

Analyse (Randomisiertes Quicksort) 248 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) 249 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 (log n 1) k + log n n k=1 = n 1 + 8 ( n(n 1) (log n) n n 2 4 = 4n log n 4 log n 3 4n log n n 1 k=n/2+1 ( n 2 + 1 ) ) k

Analyse (Randomisiertes Quicksort) 250 Theorem Im Mittel benötigt randomisiertes Quicksort O(n log n) Vergleiche.

Praktische Anmerkungen Rekursionstiefe im schlechtesten Fall: n 1 8. Dann auch Speicherplatzbedarf O(n). Kann vermieden werden: Rekursion nur auf dem kleineren Teil. Dann garantiert O(log n) Rekursionstiefe und Speicherplatzbedarf. 8 Stack-Overflow möglich! 251

Quicksort mit logarithmischem Speicherplatz 252 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 Der im ursprünglichen Algorithmus verbleibende Aufruf an Quicksort(A[l,..., r]) geschieht iterativ (Tail Recursion ausgenutzt!): die If-Anweisung wurde zur While Anweisung.

Praktische Anmerkungen 253 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.