WikiDer > Mergesort

Mergesort
Zusammenführen, sortieren

Zusammenführen, sortieren ist ein rekursivSortieralgorithmus, laut der teilen und erobernMergesort funktioniert, indem man zuerst eine Reihe von zu sortierenden Elementen in zwei ungefähr gleich große (unsortierte) Reihen aufteilt und dies wiederholt, bis nur noch Reihen mit einem Element übrig sind. Dann werden die Reihen wieder zu zweit zusammengeführt, so wie es war, Vergleichen Sie immer die Vorderseite der beiden sortierten Reihen, um zu bestimmen, welches das nächste Element in der sortierten Reihe sein soll.Dieses Zusammenführen von sortierten Reihen wird auf einer höheren und höheren Ebene wiederholt, bis eine weitere (natürlich sortierte) Reihe vorbei ist .

Pseudocode

Hier ist ein Pseudocode-Beispiel ausgehend von der Folge {2,1,2*,3}:

dividiere {2,1,2*,3} in zwei Teile: {2,1} und {2*,3}
teilen Sie {2,1} in zwei Teile: {2} und {1}
füge {2} und {1} hinzu, um {1,2}
teilen {2*,3} in zwei Teilen: {2*} und {3}
füge hinzu {2*} und {3} zusammen zu {2*,3}
füge {1,2} und {2 . hinzu*,3} um zusammen zu {1,2,2*,3}

Wenn das Zusammenführen in der gleichen Reihenfolge wie das Teilen erfolgt, lautet der Algorithmus stabil: die Ordnung von 2 und 2* im Beispiel bleibt die Sortierung unverändert.

Das Komplexitätsgrad von mergesort ist der schlimmste Fall, wenn n Elemente sortiert werden Ö(n log n), dessen Code, der zwei sortierte Zeilen verbindet, in O(n)-Zeit (linear) abläuft.

Prolog-Beispiel

Hier ist eine Beschreibung von mergesort in Prolog - eine logische Programmiersprache. Prolog hat keine Arrays. Sowohl Sammlungen als auch Arrays werden oft durch "Listen" dargestellt: eine leere Liste ist [] und eine Liste, deren erstes Element X ist und die nach X kommt, wird als [X|T] dargestellt, die nach % kommt, ist Kommentar merge sort merge ist als Prozedur mit zwei Argumenten: das erste istEingang (die Liste, die wir sortieren möchten) und die zweite ist Ausgabe, nämlich das Ergebnis des Sortiervorgangs

Zusammenführen, sortieren([],[])./* leere Liste ist leere sortierte Liste */Zusammenführen, sortieren([X],[X])./* Liste mit 1 Element ist eine sortierte Liste mit 1 Element */Zusammenführen, sortieren(Aufführen,Sortierte Liste):-/* mergeSortieren Sie die Liste und sammeln Sie das Ergebnis in der sortierten Liste */Teilt(Aufführen,H1,H2),/* teile die Liste in 2 Hälften */Zusammenführen, sortieren(H1,S1),/* diese Hälften zusammenführen */Zusammenführen, sortieren(H2,S2),/* diese Hälften zusammenführen */verschmelzen(S1,S2,Sortierte Liste)./* die 2 sortierten Hälften zusammenführen */Teilt([],[],[])./* das Aufteilen einer leeren Liste ergibt 2 leere Hälften */Teilt([X],[X],[])./* split with 1 element ergibt 1 Hälfte mit diesem Element darin und eine leere Liste (wenn es eine ungerade Liste ist)*/Teilt([X,Ja|T],[X|H1],[Ja|H2]):-/* X und Y zur ersten bzw. zweiten Hälfte hinzufügen */Teilt(T,H1,H2)./* und fahre mit dem Rest der Liste fort */verschmelzen([],[],[])./* Zusammenführen von 2 leeren Listen ist eine leere Liste */verschmelzen(X,[],X)./* Zusammenführen einer leeren Liste mit einer nicht leeren Liste ist diese nicht leere Liste */verschmelzen([],Ja,Ja)./* Zusammenführen einer leeren Liste mit einer nicht leeren Liste ist diese nicht leere Liste */verschmelzen([Kopf1|Schwanz1],[Kopf2|Schwanz2],[Kopf1|so]):-/* wenn head1 kleiner als head2 ist, füge head1 der zusammengeführten Liste hinzu*/Kopf1<Kopf2,/* Prädikat*/!,verschmelzen(Schwanz1,[Kopf2|Schwanz2],so)./* und weiter mit tail1 und der ganzen zweiten Liste*/verschmelzen([H1|T1],[H2|T2],[H2|so]):-/* wenn head1 größer als head2 ist, füge head2 der zusammengeführten Liste hinzu */verschmelzen([H1|T1],T2,so)./* und weiter mit tail2 und der ganzen ersten Liste */

Java-Beispiel

Das untere Java-Code-Snippet sortiert die Array ao (das kann ein String-Array sein, aber auch ein Array eines anderen Typs, solange es Vergleichbar ist):

LeereZusammenführen, sortieren(Vergleichbar[]ähm){wenn(ähm.Länge<=1){Rückkehr;// getan}/* Teilen */inti1=ähm.Länge/2;Vergleichbar[]aoL=NeuVergleichbar[i1];zum(intich=0;ich<i1;ich){aoL[ich]=ähm[ich];}Vergleichbar[]aoR=NeuVergleichbar[ähm.Länge-i1];zum(intich=i1;ich<ähm.Länge;ich){aoR[ich-i1]=ähm[ich];}/* Teilstrings sortieren */Zusammenführen, sortieren(aoL);Zusammenführen, sortieren(aoR);/* Teilstrings (Reißverschlüsse) zusammenführen *//* ua können wir wiederverwenden */intiL=0;intiR=0;zum(intich=0;ich<ähm.Länge;ich){wenn(iL>=aoL.Länge){ähm[ich]=aoR[iR  ];}sonstwenn(iR>=aoR.Länge){ähm[ich]=aoL[iL  ];}sonstwenn(aoL[iL].vergleichen mit(aoR[iR])<=0){ähm[ich]=aoL[iL  ];}sonst{ähm[ich]=aoR[iR  ];}}}

C-Beispiel

Der nächste CFunktion sortiert das Array "Daten" nach "Länge" Anzahl der Elemente gemäß dem Mergesort-Algorithmus:

LeereZusammenführen, sortieren(intTermine[],intLänge){inti1=0,i2=0;// aktueller Platz in Gruppenint*Gruppe 1,*Gruppe2;// GruppenstartintLänge1,Länge2;// Gruppenlängenintsortiert[Länge];// sortierte Datenintvorübergehend;wenn(Länge>1){// Wenn Länge 1 oder weniger ist, gibt es nichts zu sortieren// in Gruppen aufteilenGruppe 1=Termine;Gruppe2=TermineLänge/2;// finde die Länge jeder GruppeLänge1=Länge/2;Länge2=Länge-Länge1;// Zusammenführen, sortierenZusammenführen, sortieren(Gruppe 1,Länge1);Zusammenführen, sortieren(Gruppe2,Länge2);// zusammenführenzum(vorübergehend=0;vorübergehend<Länge;vorübergehend){wenn(i1==Länge1){// Gruppe beenden1, Strom von 2 nehmensortiert[vorübergehend]=Gruppe2[i2];i2;}sonstwenn(i2==Länge2){// Gruppe2 beenden, Strom von 1 nehmensortiert[vorübergehend]=Gruppe 1[i1];i1;}sonstwenn(Gruppe 1[i1]<Gruppe2[i2]){// Strom von 1 ist kleiner, nimm dassortiert[vorübergehend]=Gruppe 1[i1];i1;}sonst{// Strom von 2 ist kleiner, nimm dassortiert[vorübergehend]=Gruppe2[i2];i2;}}// nach Daten sortiert kopierenmemcpy(Termine,sortiert,Länge*Größe von(int));}}

Python-Beispiel

Python-Code

defZusammenführen, sortieren(Warteschlange):wennlen(Warteschlange)<=1:RückkehrWarteschlange#StoppbedingungMitte=int(len(Warteschlange)/2)links=Zusammenführen, sortieren(Warteschlange[:Mitte])#rekursiver Aufruf im linken TeilRecht=Zusammenführen, sortieren(Warteschlange[Mitte:])#rekursiver Aufruf am rechten TeilZähler=0währendlen(links)!=0undlen(Recht)!=0:wennlinks[0]<Recht[0]:#vergleiche den ersten von links mit dem ersten von rechtsWarteschlange[Zähler]=links.Puppe(0)#lösche zuerst von links und füge sie in die Reihe einsonst:Warteschlange[Zähler]=Recht.Puppe(0)#lösche die erste von rechts und füge sie in die Zeile einZähler =1RückkehrWarteschlange[:-len(linksRecht)]linksRecht#oder links oder rechts ist leer, also ist das möglich