Der schnelle Sortieralgorithmus kann in die folgenden Schritte unterteilt werden
Pivot identifizieren.
Partitionieren Sie die verknüpfte Liste basierend auf Pivot.
Teilen Sie die verknüpfte Liste rekursiv in zwei Teile.
Wenn ich immer das letzte Element als Pivot wähle, dauert die Identifizierung des Pivot-Elements (1. Schritt) Mal.
Nachdem wir das Pivot-Element identifiziert haben, können wir seine Daten speichern und mit allen anderen Elementen vergleichen, um den richtigen Partitionspunkt zu ermitteln (2. Schritt). Jeder Vergleich benötigt Zeit, da wir die Pivot-Daten speichern, und jeder Swap benötigt O ( 1 ) Zeit. Insgesamt dauert es also O ( n ) Zeit für n Elemente.
Die Wiederholungsbeziehung lautet also:
ist O ( n log n ) und entspricht der Sortierung beim Zusammenführen mit einer verknüpften Liste.
Warum wird die Sortierung beim Zusammenführen für verknüpfte Listen der schnellen Sortierung vorgezogen?
Antworten:
Das Speicherzugriffsmuster in Quicksort ist zufällig, und die sofort einsatzbereite Implementierung ist vorhanden. Daher werden viele Auslagerungsversuche durchgeführt, um ein geordnetes Ergebnis zu erzielen.
Während die Zusammenführungssortierung extern ist, ist ein zusätzliches Array erforderlich, um das geordnete Ergebnis zurückzugeben. In Arrays bedeutet dies zusätzlichen Speicherplatzaufwand. In dem Fall, dass eine verknüpfte Liste vorhanden ist, kann der Wert herausgezogen und das Zusammenführen von Knoten gestartet werden. Der Zugriff erfolgt sequentieller.
Aus diesem Grund ist die Quicksortierung für verknüpfte Listen keine natürliche Wahl, während das Sortieren durch Zusammenführen große Vorteile bringt.
Die Landau-Notation könnte (mehr oder weniger, weil Quicksort immer noch ) zustimmen, aber die Konstante ist viel höher.O ( n2)
Im Durchschnitt sind beide Algorithmen in so dass der asymptotische Fall derselbe ist, aber die Präferenz liegt ausschließlich an der versteckten Konstante und manchmal ist die Stabilität das Problem (Quicksort ist von Natur aus instabil, Mergsort ist stabil).O (nlogn )
quelle
Dies ist der Algorithmus, den der Linux-Kernel zum Sortieren seiner verknüpften Listen verwendet. Allerdings mit einigen zusätzlichen Optimierungen wie dem Ignorieren des
previous
Zeigers während aller bis auf den letzten Zusammenführungsvorgang.quelle
Sie können Merge-Sortierung, Partition-Sortierung, Baum-Sortierung und Vergleichsergebnisse
schreiben. Es ist ziemlich einfach, Baum-Sortierung zu schreiben, wenn Sie etwas zusätzlichen Platz zulassen.
Für Baum-Sortierung muss jeder Knoten der verknüpften Liste zwei Zeiger haben, auch wenn wir einfach verknüpfte Liste
in verknüpfter Liste sortieren Ich bevorzuge das Einfügen und Löschen, anstatt die
Hoare-Partition auszutauschen. Dies ist nur für doppelt verknüpfte Listen möglich
Dieser Code muss verbessert werden.
Zuerst sollten wir den zusätzlichen Speicher auf die Rekursionsanforderungen beschränken,
dann sollten wir versuchen, die Rekursion durch eine Iteration zu ersetzen.
Wenn wir den Algorithmus weiter verbessern möchten, sollten wir den Self Balancing Tree verwenden
quelle
Quicksort
Vielleicht zeige ich Schritte für Quicksort
Wenn die Liste mehr als einen Knoten enthält
erste Unterliste enthält Knoten mit Schlüsseln, die kleiner als der Pivot-Schlüssel sind. Die
zweite Unterliste enthält Knoten mit Schlüsseln, die gleich dem Pivot-Schlüssel sind. Die
dritte Unterliste enthält Knoten mit Schlüsseln, die größer als der Pivot-Schlüssel sind
Zu 1.
Wenn wir Pivot schnell auswählen möchten, ist die Auswahl begrenzt.
Wir können
Kopfknoten oder Endknoten auswählen. Unsere Liste muss auf den Knoten ausgerichtet sein, wenn unser Pivot
schnell verfügbar sein soll. Andernfalls müssen wir nach Knoten suchen
Zu 2.
Wir können Warteschlangenoperationen für diesen Schritt verwenden.
Zuerst entfernen wir den Knoten aus der ursprünglichen verknüpften Liste und
vergleichen seinen Schlüssel mit dem Pivot-Schlüssel und stellen den Knoten in die richtige Unterliste.
Unterlisten werden aus vorhandenen Knoten erstellt und es ist nicht erforderlich,
Speicher für neue Knoten zuzuweisen
Der Zeiger auf den Endknoten ist nützlich, da Warteschlangenoperationen
und Verkettungen bei Vorhandensein dieses Zeigers schneller ausgeführt werden
quelle