Aufgabe vollständig gelöst
-
Genaue Vorhersage der Anzahl der Vertauschungen bei Bubble Sort für 64 umgekehrte Elemente 7 Schritte
Führen Sie das Rennen mit der Voreinstellung umgekehrt aus — 64 Elemente, das größte zuerst. Sagen Sie die Anzahl der Vertauschungen von Bubblesort exakt voraus, nicht seine Wachstumsordnung; erklären Sie dann, was jeden Algorithmus, der nur Nachbarn tauscht, daran hindert, dieses Ergebnis zu unterbieten.
-
Eine Inversion ist ein Paar, das in der falschen relativen Reihenfolge steht. Eine umgekehrte Eingabe ist der Extremfall: Für jedes i < j ist das frühere Element das größere, sodass jedes Paar invertiert ist und ihre Anzahl der Gesamtzahl aller Paare entspricht. Bestimmen Sie diese Zahl, bevor sich irgendetwas bewegt — sie erweist sich als das gesamte Problem.
-
Bubblesort tauscht nur benachbarte Elemente, und das auch nur, wenn sie nicht sortiert sind. Ein solcher Tausch korrigiert genau dieses eine Paar und stört kein anderes, da die zwei bewegten Elemente dieselbe Beziehung zu allem außerhalb behalten. Eine Vertauschung, eine Inversion — niemals zwei, niemals keine.
-
Sortiert bedeutet null Inversionen. Bei 2.016 zu beginnen und pro Vertauschung genau eine zu entfernen, lässt keinen Spielraum: Die Anzahl der Vertauschungen ist erzwungen. Das Bedienfeld gibt 2.016 Vertauschungen aus, und das ist eine Identität und nicht bloß eine Worst-Case-Schranke.
-
Vergleiche sind eine eigene Zählung, die hier zufällig übereinstimmt. Durchlauf i prüft j = 0 … 62 − i, sodass die Summe 63 + 62 + ⋯ + 1 beträgt — dieselbe 2.016, die die Zeile Bubble Worst-Case n(n−1)/2 zeigt. Gleiche Anzahlen bedeuten, dass jeder einzelne Vergleich eine Inversion gefunden hat, was hier „Worst Case“ bedeutet. Der Zähler unter dem Titel jedes Bedienfelds zählt einen Schritt pro Vergleich plus einen pro Vertauschung, sodass er vor dem Start Schritt 0 / 4.032 anzeigt, und die Schaltfläche › verbraucht genau einen dieser Schritte pro Klick. Das O(n²) neben dem Titel ist eine Beschriftung, kein Zähler.
-
Generalisieren Sie nun Schritt 2, denn genau das nutzt Quicksort aus. Das Vertauschen zweier Einträge im Abstand von d Positionen lässt jedes Paar, das mit einem Element außerhalb der Spanne gebildet wird, in der Summe unangetastet: Ein solches Element wird erneut mit dem anderen Ende verglichen, die zwei Vergleiche tauschen die Plätze und sein Beitrag bleibt unverändert. Was sich bewegen kann, ist das Paar selbst sowie die 2(d − 1) Paare, die jedes Ende mit den d − 1 Einträgen dazwischen bildet. Höchstens 2d − 1 Inversionen können pro Tausch verschwinden, und das Setzen von d = 1 liefert wieder die einzelne Inversion aus Schritt 2.
-
Die erste Partitionierung von Quicksort wählt das mittlere Element als Pivot, a[31] = 33, und tauscht (0, 63), (1, 62), … , (31, 32) — 32 Vertauschungen in den Abständen 63, 61, … , 1. Schritt 5 begrenzt ihre kombinierte Wirkung auf 2.016 Inversionen, und dieser einzelne Durchlauf hinterlässt das Array vollständig sortiert, sodass genau 2.016 entfernt wurden. Die Obergrenze wird mit Gleichheit erreicht: Jede der 32 Vertauschungen hat ihr eigenes Maximum erzielt.
-
Die beiden Algorithmen konkurrieren also nicht in der Klugheit, sondern in der Reichweite. Die für Quicksort angezeigten 334 Vergleiche und 64 Vertauschungen ergeben in der Summe 398 auf seinem Zähler — und nur 32 dieser Vertauschungen bewegen tatsächlich etwas, während die anderen 32 das Pivot betreffen, das in bereits sortierten Abschnitten mit sich selbst getauscht wird. Seine 334 liegen zudem unter der angezeigten n·log₂n-Referenz von 384, da das mittlere Element einer umgekehrten Folge ihr Median ist und somit jede Aufteilung gleichmäßig erfolgt.
Antwort
2.016 Vertauschungen und 2.016 Vergleiche — die 4.032 Schritte auf dem Zähler. Und 2.016 ist keine reine Eigenschaft von Bubblesort: Es ist eine untere Schranke für eine ganze Familie. Jeder Algorithmus, der darauf beschränkt ist, benachbarte Elemente zu tauschen — Insertionsort, Cocktailshaker-Sort, Gnomesort oder einer, den noch niemand geschrieben hat —, löscht nach Schritt 2 höchstens eine Inversion pro Vertauschung; daher benötigen alle bei dieser Eingabe mindestens 2.016 Vertauschungen und alle liegen bei umgekehrten Daten in Ω(n²), und zwar aufgrund des Modells, in dem sie arbeiten, nicht weil sie ungeschickt wären. Quicksort entkommt dieser unteren Schranke, indem es ihm gestattet ist, ein Element um 63 Positionen auf einmal zu verschieben: 2.016 Inversionen, beseitigt durch 32 echte Vertauschungen, macht 63 Inversionen pro Vertauschung, und Schritt 5 besagt, dass dies das Maximum ist, das eine einzelne Vertauschung über diese Distanz hätte erreichen können. Das Bedienfeld berechnet weder die Anzahl der Inversionen noch die daraus folgende untere Schranke.
-
Lernpfad
Arbeit zählen, nicht Sekunden
Quellen (1)
- Insight block 3 — quicksort as its author published it: C. A. R. Hoare, "Quicksort." The Computer Journal 5(1), 10–16, 1962. The algorithm first appeared the year before as C. A. R. Hoare, "Algorithm 64: Quicksort", Communications of the ACM 4(7), 321, 1961.