Worst case

35

Ich habe Probleme bei der Suche gute Ressourcen , die einem schlimmsten Fall geben anstelle stabilem Sortieralgorithmus. Kennt jemand gute Ressourcen?O(nlnn)

Nur zur Erinnerung: An der richtigen Stelle wird das übergebene Array verwendet, und der Sortieralgorithmus darf nur konstanten zusätzlichen Speicherplatz belegen. Stabil bedeutet, dass Elemente mit demselben Schlüssel im sortierten Array in derselben Reihenfolge wie im Original angezeigt werden.

Beispielsweise ist die naive Zusammenführungssortierung der schlechteste Fall und stabil, verwendet jedoch zusätzlichen Raum. Standard-Quicksort kann stabil gemacht werden, ist vorhanden, aber der schlimmste Fall ist . Heapsort ist vorhanden, im schlimmsten Fall aber nicht stabil. Wikipedia hat eine schöne Tabelle, welche Sortieralgorithmen welche Nachteile haben. Beachten Sie, dass es keinen Sortieralgorithmus gibt, der alle drei Stabilitätsbedingungen enthält, nämlich den ungünstigsten Fall und vorhanden ist.O ( n ) O ( n 2 ) O ( n ln n ) O ( n ln n )O(nlnn)O(n)O(n2)O(nlnn)O(nlnn)

Ich habe eine Veröffentlichung mit dem Titel "Practical in-place mergesort" von Katajainen, Pasanen und Teuhola gefunden, in der behauptet wird, dass eine stabile Mergesort-Variante mit dem Worst-Case-Wert vorliegt. Wenn ich ihre Ergebnisse richtig verstehe, verwenden sie (Bottom-Up?) Rekursiv eine Mergesort-Methode für das erste des Arrays und das letztere des Arrays und verwenden das zweite als Arbeitsbereich für die Zusammenführung. Ich lese das noch immer durch, daher sind weitere Informationen darüber, ob ich die Ergebnisse richtig interpretiere, sehr willkommen.1O(nlnn) 114 11214

Ich wäre auch sehr interessiert an einem Worst-Case- anstelle einer stabilen Quicksorte. Soweit ich weiß, erfordert das Ändern von Quicksort in den ungünstigsten Fall die Auswahl eines geeigneten Drehpunkts, der die Stabilität zerstören würde, die er sonst normalerweise genießen würde.O ( n ln n )O(nlnn)O(nlnn)

Dies ist rein theoretisch interessant und ich habe keine praktische Anwendung. Ich möchte nur den Algorithmus kennen, der alle drei dieser Funktionen hat.

user834
quelle
Es gibt eine ähnliche Frage auf SO hier mit einer Antwort, die der Referenz mir in der Frage zur Verfügung gestellt gibt. Ich glaube, dies ist keine doppelte Frage, da ich um weitere Erläuterungen, mehr Literatur und mit etwas Glück eine Beschreibung des Algorithmus bitte.
user834
1
Siehe diese Frage auf math.stackexchange.com.
Tsuyoshi Ito
Warum würde eine andere Art der Auswahl eines Pivots in QuickSort seine Stabilität zerstören?
Svick
@svick, die einzige Möglichkeit, QuickSort zum Worst-Case- besteht darin, den Pivot intelligenter als zufällig zu wählen. Die Art und Weise, wie ich das gelernt habe, war die Verwendung des Auswahlalgorithmus, der den Median-of-Medians-Algorithmus verwendet, der die Stabilität zerstört. Wenn ich etwas verpasst habe, lassen Sie es mich bitte wissen. O(nlnn)
User834
@ TsuyoshiIto, erwägen Sie, dies zu einer Antwort zu machen. Wenn Sie den Algorithmus kurz skizzieren könnten, wäre das meiner Meinung nach auch sehr hilfreich.
User834

Antworten:

6

Es gibt mehrere Algorithmen, die alle oben aufgeführt sind, und fast alle wurden in den letzten 30 Jahren erfunden.

Am schönsten ist wohl die Klasse der Algorithmen mit der Bezeichnung Block sort , einschließlich der Version (WikiSort) von Kim und Kutzner aus dem Jahr 2008. Sie ist nicht nur stabil und vollständig an Ort und Stelle (O (1) -Speicher-Overhead im transdichotomen Modell) ist auch anpassungsfähig und benötigt daher weniger Schritte, um nahezu sortierte Listen zu sortieren, was im Fall einer bereits sortierten Liste zu O (n) -Vergleichen konvergiert. Eine Implementierung in C, C ++ und Java finden Sie hier: https://github.com/BonzaiThePenguin/WikiSort

Interessant ist auch der GrailSort-Algorithmus (ebenfalls eine Block-Sortierung) von Huang und Langston (1989-1992), der WikiSort in mehreren Arten von Testfällen sogar übertrifft. Eine C ++ - Implementierung finden Sie hier: https://github.com/Mrrl/GrailSort

Quintopie
quelle
8

Sie können ein direktes, stabiles Mergesort schreiben. Sehen Sie diese für weitere Einzelheiten. In den eigenen Worten des Autors:

Ein wunderschöner In-Place-Merge-Algorithmus. Testen Sie es auf invertierten Arrays, um zu verstehen, wie Rotationen funktionieren. Schnellste an Ort und Stelle bekannte stabile Sorte. Keine Explosionsgefahr eines Stapels. Kosten: eine relativ hohe Anzahl von Zügen. Stack kann auch noch teuer sein. Dies ist eine Zusammenführungssorte mit einer Smart-In-Place-Zusammenführung, die die Sub-Arrays "dreht". Dieser Code wird vollständig aus der C ++ stl-Bibliothek kopiert und in Java übersetzt.

Ich werde den Code hier nicht kopieren, aber Sie finden ihn unter dem Link oder in der C ++ STL. Bitte lassen Sie mich wissen, wenn Sie möchten, dass ich versuche, eine detailliertere Beschreibung der Vorgänge hier zu geben.

Patrick87
quelle
8
O(lnn)O(1)O(lnn)
Knuth spricht dies auch in TAoCP an.
Raphael
O(nln2n)
1

Bitte nehmen Sie dies als langen Kommentar zu einigen praktischen Überlegungen. Obwohl dies keine Antwort auf Ihre Frage ist, könnte Sie diese Python-Diskussion interessieren:

lg(N!)N-1

[...]

Das Zusammenführen benachbarter Läufe der Längen A und B an Ort und Stelle ist sehr schwierig . Es sind theoretische Konstruktionen bekannt, die dies können, aber für den praktischen Gebrauch sind sie zu schwierig und zu langsam . Aber wenn wir einen temporären Speicher von min (A, B) haben, ist es einfach.

Quelle: bugs.python.org , Autor: Tim Peters

O(nLogn)

Beachten Sie auch, dass Timsort bei bereits sortierten Arrays gute Ergebnisse erzielt.

Daher verwendet Python Timsort (das ist Mergesort mit einigen Verbesserungen) und, wie ich vor einigen Jahren bei der Java-Implementierung nachgeschlagen habe, auch Mergesort (ich denke, sie verwenden jetzt auch Timsort).

Martin Thoma
quelle