Einfügungssortierung gegen Blasensortierungsalgorithmen


84

Ich versuche, ein paar Sortieralgorithmen zu verstehen, aber ich habe Mühe, den Unterschied zwischen dem Blasensortierungs- und dem Einfügesortieralgorithmus zu erkennen.

Ich weiß, dass beide O (n 2 ) sind, aber es scheint mir, dass die Blasensortierung nur den Maximalwert des Arrays für jeden Durchgang nach oben sprudelt, während die Einfügesortierung bei jedem Durchgang nur den niedrigsten Wert nach unten senkt. Tun sie nicht genau dasselbe, aber in verschiedene Richtungen?

Bei der Einfügungssortierung beginnt die Anzahl der Vergleiche / potenziellen Swaps bei Null und steigt jedes Mal an (dh 0, 1, 2, 3, 4, ..., n). Bei der Blasensortierung tritt jedoch dasselbe Verhalten auf, jedoch am Ende von die Sortierung (dh n, n-1, n-2, ... 0), da die Blasensortierung beim Sortieren nicht mehr mit den letzten Elementen verglichen werden muss.

Trotz alledem scheint es ein Konsens zu sein, dass die Einfügungssortierung im Allgemeinen besser ist. Kann mir jemand sagen warum?

Bearbeiten: Ich interessiere mich hauptsächlich für die Unterschiede in der Funktionsweise der Algorithmen, nicht so sehr für ihre Effizienz oder asymptotische Komplexität.


1
Dies ist an anderer Stelle gut dokumentiert: siehe z. B. en.wikipedia.org/wiki/Sorting_algorithm . Eher sinnlos hier zu duplizieren und eine gute Antwort wird expansiv sein.
Bathsheba

@Bathsheba 75 Personen, die gestimmt haben, und 88.000, die die Frage gesehen haben, scheinen anderer Meinung zu sein; )
Parsecer

@ Parsecer: Ha! Jetzt muss ich die Antworten überprüfen. Die aktuell am höchsten bewertete Antwort ist nützlich. Ich bin mir nicht sicher über die anderen. Hier sind einige Wiederholungspunkte, die durch das Abstimmen der Antwort verloren gegangen sind. Die Behauptung "Deshalb ist die Einfügungssortierung schneller als die Blasensortierung" in der akzeptierten Antwort ist nicht unbedingt wahr.
Bathseba

@Bathsheba Oh nein
Parsecer

Antworten:


38

Bei der Blasensortierung in der i-ten Iteration haben Sie ni-1 innere Iterationen (n ^ 2) / 2 insgesamt, aber bei der Einfügungssortierung haben Sie maximal i Iterationen im i-ten Schritt, aber i / 2 im Durchschnitt, da Sie die innere Schleife stoppen können früher, nachdem Sie die richtige Position für das aktuelle Element gefunden haben. Sie haben also (Summe von 0 bis n) / 2, was (n ^ 2) / 4 insgesamt ist;

Aus diesem Grund ist die Einfügesortierung schneller als die Blasensortierung.


2
Die Erklärung des Algorithmus ist überall im Internet, denke ich.
Sasha.sochka

3
Ja, aber es scheint, dass das OP immer noch keinen Unterschied in den Mechanismen
erkennt

15
Nun, Sie können davon ausgehen, dass ich die Grundlagen verstehe . Was ich wollte, war ein Vergleich, und das ist wirklich ziemlich gut. Die Idee ist also, dass während die Einfügungssortierung das i-te Element nach unten sinkt und die Blasensortierung dazu führt, dass es nach oben sprudelt, die Einfügungssortierung nicht dazu führt, dass es ganz nach unten fällt, sondern nur, dass es in die richtige Position fällt der bereits sortierte Abschnitt. Somit werden weniger Vergleiche / Swaps durchgeführt. Ist das richtig?
Migwell

1
Was? "Sie haben also (Summe von 0 bis n) / 2, was (n ^ 2) / 4 insgesamt ist." Das erfordert bitte einige Erklärungen! 0 + 1 + 2 + 3 + 4 + 5 = 15; 15/2 = 7,5; 7,5 * 4 = 30; sqrt (30) = Kauderwelsch
John Smith

@ JohnSmith Ich glaube, es gibt einen kleinen Fehler in der Antwort. Die Summe von 1 bis n ist n * (n + 1) / 2, da es sich um eine dreieckige Zahl handelt. Weitere Erklärungen finden Sie unter Dreieckszahl. Das geteilt durch 2 ist also nur n * (n + 1) / 2.
CognizantApe

121

Sortieren durch Einfügen

Nach i Iterationen werden die ersten i Elemente geordnet.

In jeder Iteration wird das nächste Element durch den sortierten Abschnitt geblasen, bis es die richtige Stelle erreicht:

sorted  | unsorted
1 3 5 8 | 4 6 7 9 2
1 3 4 5 8 | 6 7 9 2

Die 4 wird in den sortierten Bereich gesprudelt

Pseudocode:

for i in 1 to n
    for j in i downto 2
        if array[j - 1] > array[j]
            swap(array[j - 1], array[j])
        else
            break

Blasensortierung

Nach i Iterationen sind die letzten i Elemente die größten und geordneten.

Durchsuchen Sie in jeder Iteration den unsortierten Abschnitt, um das Maximum zu ermitteln.

unsorted  | biggest
3 1 5 4 2 | 6 7 8 9
1 3 4 2 | 5 6 7 8 9

Die 5 wird aus dem unsortierten Bereich gesprudelt

Pseudocode:

for i in 1 to n
    for j in 1 to n - i
         if array[j] > array[j + 1]
             swap(array[j], array[j + 1])

Beachten Sie, dass typische Implementierungen vorzeitig beendet werden, wenn während einer der Iterationen der äußeren Schleife keine Swaps durchgeführt werden (da dies bedeutet, dass das Array sortiert ist).

Unterschied

Beim Einfügen werden Sortierelemente in den sortierten Abschnitt gesprudelt, während beim Blasensortieren die Maxima aus dem unsortierten Abschnitt gesprudelt werden.


10
Danke, das ist sehr klar! Ich denke, die Hauptsache, die ich hervorheben musste, ist, dass die break- Anweisung in Insertion Sort bedeutet, dass jede Iteration vorzeitig beendet werden kann: dh wenn sie ihre Position im sortierten Abschnitt gefunden hat. Die Blasensortierung erfordert, dass der Austausch fortgesetzt wird, bis das größte Element im unsortierten Abschnitt den sortierten Abschnitt erreicht, sodass er niemals vorzeitig beendet wird. Es ist eine fantastische Zusammenfassung, also +1
Migwell

4
Ich denke, dass dies die beste Antwort sein sollte :)
Adelin

2
Plus 1 für die Klarheit, den didaktischen Wert und für die Hauptschleifeninvarianten jedes Algorithmus. Es ist schade , es enthält nicht ausdrücklich den Vergleich der Komplexität (in Abhängigkeit von ausgedrückt n ), trotzdem kann ich es eine bessere Antwort als die akzeptierte man berücksichtigen, da von diesem Ich kann sehen den Unterschied.
Honza Zidek

Kann ich fragen, warum Sie Ihren Artikel in Ihrem Insertation Pseudo-Code bei jedem Schritt austauschen? wenn (a [j-1]> a [j]) dann a [j] = a [j-1] SONST wenn (a [j-1] <e && a [j]> e) als a [j] = e; Pause; , wobei e der Artikel ist, muss sortiert werden. Mit dieser Lösung tauschen Sie nicht bereits sortierte Elemente aus, sondern kopieren sie nur. Ich freue mich auf Ihre Erklärung, da ich etwas verwirrt bin.
Karoly

@ Karoly, ich habe meine Version gewählt, weil es einfacher ist. Ihre ist etwas schneller, es ist gut, dass Sie darauf hinweisen. Wikipedia beschreibt beide Versionen.
Tom

16

Einen weiteren Unterschied habe ich hier nicht gesehen:

Die Blasensortierung hat 3 Wertzuweisungen pro Swap : Sie müssen zuerst eine temporäre Variable erstellen, um den Wert zu speichern, den Sie vorantreiben möchten (Nr. 1), und dann die andere Swap-Variable an die Stelle schreiben, an der Sie den Wert gerade gespeichert haben von (Nr. 2) und dann müssen Sie Ihre temporäre Variable an die Stelle anderer Stelle (Nr. 3) schreiben. Sie müssen dies für jeden Punkt tun - Sie möchten vorwärts gehen -, um Ihre Variable an den richtigen Punkt zu sortieren.

Mit der Einfügesortierung setzen Sie Ihre Variable in eine temporäre Variable und setzen dann alle Variablen 1 Stelle rückwärts vor diese Stelle, solange Sie die richtige Stelle für Ihre Variable erreichen. Das ergibt 1 Wertzuweisung pro Spot . Am Ende schreiben Sie Ihre temporäre Variable in die Stelle.

Das macht auch weit weniger Wertzuweisungen.

Dies ist nicht der stärkste Geschwindigkeitsvorteil, aber ich denke, es kann erwähnt werden.

Ich hoffe, ich habe mich verständlich ausgedrückt, wenn nicht, tut mir leid, ich bin kein gebürtiger Brite


1
"und dann alle Variablen vor diesen Punkt 1 Punkt rückwärts stellen" - und erfordert das nicht auch eine Menge Zuweisungen, um die Daten zu verschieben? (vorausgesetzt, die Daten werden ohnehin zusammenhängend gespeichert, keine verknüpfte Liste)
Mark K Cowan

@MarkKCowan, ja, hier wird die Einfügungssortierung nach 'Punkt' vorgenommen, wie der obige Benutzer es ausdrückte. Grundsätzlich kann die Einfügesortierung mit einer Zuweisung in der inneren Schleife geschrieben werden, während bubblesort 3 Zuweisungen in der inneren Schleife hat.
JSQuareD

9

Der Hauptvorteil der Einfügesortierung besteht darin, dass es sich um einen Online-Algorithmus handelt. Sie müssen nicht alle Werte am Start haben. Dies kann nützlich sein, wenn Daten aus dem Netzwerk oder einem Sensor verarbeitet werden.

Ich habe das Gefühl, dass dies schneller wäre als andere herkömmliche n log(n)Algorithmen. Denn die Komplexität würde n*(n log(n))zB darin bestehen, jeden Wert aus stream ( O(n)) zu lesen / speichern und dann alle Werte ( O(n log(n))) zu sortieren, was dazu führtO(n^2 log(n))

Im Gegenteil, mit Insert Sort müssen O(n)Werte aus dem Stream gelesen und O(n)an der richtigen Stelle platziert werden O(n^2). Ein weiterer Vorteil ist, dass Sie keine Puffer zum Speichern von Werten benötigen, sondern diese am endgültigen Ziel sortieren.


Wenn es in Ordnung ist, die Daten in der richtigen Reihenfolge zu durchlaufen, als nur ein Array zu scannen, können Sie im laufenden Betrieb viel effizienter sortieren. Fügen Sie beispielsweise Elemente in einen Binärbaum ein, sobald Sie sie erhalten. Auf diese Weise erhalten Sie die O(n log(n))gesamte geleistete Arbeit, um bei jedem Schritt eine sortierte Sammlung zu erhalten. (Eine In-Order-Durchquerung ist zu jedem Zeitpunkt O(m)). Wenn Sie am Ende nur ein sortiertes Ergebnis benötigen, aber die Sortierberechnung mit der Übertragungszeit der Daten überlappen möchten, ist ein Heap möglicherweise gut. (Und funktioniert an Ort und Stelle, wie beim Einfügen).
Peter Cordes

Auf jeden Fall sind weder Blasensortierung noch Einfügungssortierung hierfür ideal, da die Problemgrößen groß genug sind, damit die O(f(n))Komplexitätsklasse mehr zählt als Implementierungsdetails und konstante Faktoren.
Peter Cordes

Korrektur: Ein Haufen ist dafür nicht gut. Es erledigt den größten Teil der Sortierarbeit, wenn Sie Elemente in sortierter Reihenfolge entfernen, weshalb das Wachsen so billig ist. Das Ziel hier ist es, den größten Teil der Arbeit bis zum Eintreffen des letzten Elements zu erledigen.
Peter Cordes

Wenn Sie ein sortiertes Array für nEinfügungen pflegen mussten , läuft es wirklich darauf hinaus, welcher Algorithmus am besten zum Sortieren eines fast sortierten Arrays geeignet ist, bei dem sich oben ein nicht sortiertes Element befindet. Viele O(n log(n))Sortieralgorithmen befinden sich O(n)im fast sortierten Fall, sodass Sie nicht sum(M=1..n, O(M * log(M)) )arbeiten müssen. Das wäre in der Tat so O(n^2 log(n)), aber mit der richtigen Wahl des Algorithmus werden sie die O(n^2)totale Arbeit sein. Die Einfügungssortierung ist hierfür jedoch am effizientesten.
Peter Cordes

7

Die Blasensortierung ist nicht online (sie kann keinen Strom von Eingaben sortieren, ohne zu wissen, wie viele Elemente es geben wird), da sie nicht wirklich ein globales Maximum der sortierten Elemente verfolgt. Wenn ein Element eingefügt wird, müssen Sie das Sprudeln von vorne beginnen


4

Nun, die Blasensortierung ist nur dann besser als die Einfügungssortierung, wenn jemand nach Top-k-Elementen aus einer großen Liste von Zahlen sucht, dh bei der Blasensortierung nach k Iterationen erhalten Sie Top-k-Elemente. Nach k Iterationen in der Einfügesortierung wird jedoch nur sichergestellt, dass diese k Elemente sortiert sind.


2

Obwohl beide Sortierungen O (N ^ 2) sind. Die verborgenen Konstanten sind bei der Einfügungssortierung viel kleiner. Versteckte Konstanten beziehen sich auf die tatsächliche Anzahl der ausgeführten primitiven Operationen.

Wann hat die Einfügesortierung eine bessere Laufzeit?

  1. Das Array ist fast sortiert. Beachten Sie, dass die Einfügesortierung in diesem Fall weniger Operationen ausführt als die Blasensortierung.
  2. Das Array ist relativ klein: Einfügesortierung Sie verschieben Elemente, um das aktuelle Element zu platzieren. Dies ist nur dann besser als Blasensortierung, wenn die Anzahl der Elemente gering ist.

Beachten Sie, dass die Einfügungssortierung nicht immer besser ist als die Blasensortierung. Um das Beste aus beiden Welten zu erhalten, können Sie die Einfügungssortierung verwenden, wenn das Array klein ist, und wahrscheinlich die Sortierung (oder Quicksortierung) für größere Arrays zusammenführen.


2
Wenn die Anzahl der Elemente nicht gering ist, wie wäre die Blasensortierung besser? Mein Verständnis ist, dass es davon abhängt, ob das verglichene Element größer (IS) oder kleiner (BS) ist und nicht von der Anzahl der Elemente, ob Sie in IS gleiten oder in BS tauschen. Bitte korrigieren Sie mich, wenn Sie falsch liegen.
Mustafa

0

Die Blasensortierung ist unter allen Umständen fast nutzlos. In Anwendungsfällen, in denen die Einfügesortierung möglicherweise zu viele Swaps enthält, kann die Auswahlsortierung verwendet werden, da sie weniger als N Swap-Zeiten garantiert. Da die Auswahlsortierung besser ist als die Blasensortierung, hat die Blasensortierung keine Anwendungsfälle.


0

Anzahl der Swaps in jeder Iteration

  • Die Einfügesortierung führt höchstens 1 Austausch in jeder Iteration durch .
  • Die Blasensortierung führt in jeder Iteration 0 bis n Swaps durch.

Zugriff auf sortierte Teile und Ändern

  • Durch das Einfügen und Sortieren wird auf das sortierte Teil zugegriffen (und bei Bedarf geändert), um die richtige Position einer betrachteten Zahl zu finden.
  • Bei der Optimierung greift die Blasensortierung nicht auf das zu, was bereits sortiert ist.

Online oder nicht

  • Einfügesortierung ist online. Das bedeutet, dass die Einfügesortierung jeweils eine Eingabe vornimmt, bevor sie an der richtigen Position platziert wird. Es muss nicht nur vergleichen adjacent-inputs.
  • Bubble-Sort ist nicht online. Es wird nicht jeweils ein Eingang betrieben. Es behandelt eine Gruppe von Eingaben (wenn nicht alle) in jeder Iteration. Blasensortierung nur vergleichen undadjacent-inputs in jeder Iteration tauschen .

0

Sortieren durch Einfügen:

1.In der Einfügung ist ein Sortierwechsel nicht erforderlich.

2. Die zeitliche Komplexität der Einfügungssortierung beträgt Ω (n) für den besten Fall und O (n ^ 2) für den schlechtesten Fall.

3.less Komplex im Vergleich zur Blasensortierung.

4.Beispiel: Bücher in die Bibliothek einlegen, Karten anordnen.

Blasensortierung: 1. Austausch der Blasensortierung erforderlich.

2. Die zeitliche Komplexität der Blasensortierung beträgt Ω (n) für den besten Fall und O (n ^ 2) für den schlechtesten Fall.

3. Komplexer im Vergleich zur Einfügesortierung.


1
Wie kommt es, dass kein Tausch erforderlich ist? Es tauscht Elemente aus, um ein Element in die richtige Position zu bringen. Und ich würde nicht sagen, dass die Blasensortierung komplexer ist.
Parsecer

-1

Die Einfügungssortierung kann wie folgt fortgesetzt werden: " Suchen Sie nach dem Element, das sich an der ersten Position (dem Minimum) befinden soll, machen Sie Platz, indem Sie die nächsten Elemente verschieben, und setzen Sie es an die erste Position. Gut. Schauen Sie sich nun das Element an, das sich an der zweiten Position befinden soll." ... "und so weiter ...

Die Blasensortierung funktioniert anders und kann wie folgt fortgesetzt werden: " Solange ich zwei benachbarte Elemente in der falschen Reihenfolge finde, tausche ich sie aus. "


Das hilft zwar beim Einfügen, aber Ihre Erklärung zum Blasensortieren enthält nicht die tatsächlichen Schleifen, sodass ich sie nicht wirklich vergleichen kann. Die Einfügesortierung hat auch effektiv die Regel Solange ich zwei benachbarte Elemente finde, die in der falschen Reihenfolge sind, tausche ich sie aus. Die Art und Weise, wie die Schleifen funktionieren, ist unterschiedlich.
Migwell

3
Ist das nicht eine Auswahlsorte?
Harold

Oh ja das stimmt ^
Migwell
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.