# Mergesort

Mergesort (von englisch merge ‚verschmelzen‘ und sort ‚sortieren‘) ist ein stabiler Sortieralgorithmus, der nach dem Prinzip teile und herrsche (divide and conquer) arbeitet. Er wurde erstmals 1945 durch John von Neumann vorgestellt.

## Funktionsweise

Mergesort betrachtet die zu sortierenden Daten als Liste und zerlegt sie in kleinere Listen, die jede für sich sortiert werden. Die kleinen sortierten Listen werden dann im Reißverschlussverfahren zu größeren sortierten Listen zusammengefügt (engl. (to) merge), bis eine sortierte Gesamtliste erreicht ist. Das Verfahren arbeitet bei Arrays in der Regel nicht in-place, es sind dafür aber (trickreiche) Implementierungen bekannt, in welchen die Teil-Arrays üblicherweise rekursiv zusammengeführt werden. Verkettete Listen sind besonders geeignet zur Implementierung von Mergesort, dabei ergibt sich die in-place-Sortierung fast von selbst.

### Veranschaulichung der Funktionsweise

Das Bild veranschaulicht die drei wesentlichen Schritte eines Teile-und-herrsche-Verfahrens, wie sie im Rahmen von Mergesort umgesetzt werden. Der Teile-Schritt ist ersichtlich trivial (die Daten werden einfach in zwei Hälften aufgeteilt). Die wesentliche Arbeit wird beim Verschmelzen (merge) geleistet – daher rührt auch der Name des Algorithmus. Bei Quicksort ist hingegen der Teile-Schritt aufwendig und der Merge-Schritt einfacher (nämlich eine Konkatenierung).
Bei der Betrachtung des in der Grafik dargestellten Verfahrens sollte man sich allerdings bewusst machen, dass es sich hier nur um eine von mehreren Rekursionsebenen handelt. So könnte etwa die Sortierfunktion, welche die beiden Teile 1 und 2 sortieren soll, zu dem Ergebnis kommen, dass diese Teile immer noch zu groß für die Sortierung sind. Beide Teile würden dann wiederum aufgeteilt und der Sortierfunktion rekursiv übergeben, so dass eine weitere Rekursionsebene geöffnet wird, welche dieselben Schritte abarbeitet. Im Extremfall (der bei Mergesort sogar der Regelfall ist) wird das Aufteilen so weit fortgesetzt, bis die beiden Teile nur noch aus einzelnen Datenelementen bestehen und damit automatisch sortiert sind.

## Implementierung

Der folgende Pseudocode illustriert die Arbeitsweise des Algorithmus, wobei liste die zu sortierenden Elemente enthält.

## Beispiel

Im letzten Verschmelzungsschritt ist das Reißverschlussverfahren beim Verschmelzen (in der Abb. „Mischen:“) angedeutet. Blaue Pfeile verdeutlichen den Aufteilungsschritt, grüne Pfeile die Verschmelzungsschritte.
Es folgt ein Beispielcode analog zum obigen Abschnitt „Implementierung“ für den rekursiven Sortieralgorithmus. Er teilt rekursiv absteigend die Eingabe in 2 kleinere Listen, bis diese trivialerweise sortiert sind, und verschmilzt sie auf dem rekursiven Rückweg, wodurch sie sortiert werden.
Beispielcode zum Verschmelzen zweier sortierter Listen.

### Java-Implementation

Eine iterative Implementation in der Programmiersprache Java unter Verwendung von verketteten Listen könnte folgendermaßen aussehen:
(Es wird eine merge-Funktion zum Verschmelzen zweier Listen verwendet, die im Absatz darunter erläutert wird.)

#### Der Merge-Schritt im Detail

Gegeben sind zwei in sich sortierte Listen $A$ und $B$, die zu einer sortierten Liste $C$ zusammengefügt werden sollen.
Man vergleicht nun die beiden kleinsten Elemente (am Anfang der Listen $A$ und $B$), fügt das kleinere zu $C$ hinzu und nimmt es aus der jeweiligen Liste $A$ oder $B$ heraus.
Dies wird so lange wiederholt, bis eine der beiden Listen A oder B leer ist, danach wird der Rest aus der anderen Liste $A$ oder $B$ (in der noch Einträge vorhanden sind) ans Ende von $C$ gehängt.
Der Mergeschritt braucht genau immer $|A|+|B|$ Operationen, da jedes Element aus beiden Listen in konstanter Zeit gelöscht und hinzugefügt werden kann. Die Laufzeit beträgt folglich: ${\mathcal {O}}(|A|+|B|)$

## Komplexität

Mergesort ist ein stabiles Sortierverfahren, vorausgesetzt der Merge-Schritt ist entsprechend implementiert. Seine Komplexität beträgt im Worst-, Best- und Average-Case in Landau-Notation ausgedrückt stets ${\mathcal {O}}(n\cdot \log(n))$.
Damit ist Mergesort hinsichtlich der Komplexität Quicksort grundsätzlich überlegen, da Quicksort (ohne besondere Vorkehrungen) ein Worst-Case-Verhalten von $\Theta (n^{2})$ besitzt. Es benötigt jedoch zusätzlichen Speicherplatz (der Größenordnung ${\mathcal {O}}(n)$), ist also kein In-place-Verfahren.
Für die Laufzeit $T(n)$ von Mergesort bei $n$ zu sortierenden Elementen gilt die Rekursionsformel
    $T(n)=\underbrace {T(\lfloor {\tfrac {n}{2}}\rfloor )} _{\text{Aufwand, den einen Teil zu sortieren}}+\underbrace {T(\lceil {\tfrac {n}{2}}\rceil )} _{\text{Aufwand, den anderen Teil zu sortieren}}+\underbrace {{\mathcal {O}}(n)} _{\text{Aufwand, die beiden Teile zu verschmelzen}}$
mit dem Rekursionsanfang $T(1)=1$.
Nach dem Master-Theorem kann die Rekursionsformel durch $2\,T(\lfloor {\tfrac {n}{2}}\rfloor )+n$ bzw. $2\,T(\lceil {\tfrac {n}{2}}\rceil )+n$ approximiert werden mit jeweils der Lösung (2. Fall des Mastertheorems, s. dort) $T(n)={\mathcal {O}}(n\cdot \log(n))$.
Durchschnittliche und maximale Anzahl Vergleiche :
| $n$ | $S_{\varnothing }(n)$ | $S_{m}(n)$ | $(S_{m}(n)-$ $S_{\varnothing }(n))/n$ |
| 2 | 1,0000 | 1 | 0,00000 |
| 3 | 2,6667 | 3 | 0,11111 |
| 4 | 4,6667 | 5 | 0,08333 |
| 6 | 9,8333 | 11 | 0,19444 |
| 8 | 15,733 | 17 | 0,15833 |
| 12 | 29,952 | 33 | 0,25397 |
| 16 | 45,689 | 49 | 0,20694 |
| 24 | 82,059 | 89 | 0,28922 |
| 32 | 121,50 | 129 | 0,23452 |
| 48 | 210,20 | 225 | 0,30839 |
| 64 | 305,05 | 321 | 0,24920 |
| 96 | 514,44 | 545 | 0,31838 |
| 128 | 736,13 | 769 | 0,25677 |
| 192 | 1218,9 | 1281 | 0,32348 |
| 256 | 1726,3 | 1793 | 0,26061 |
| 384 | 2819,8 | 2945 | 0,32606 |
| 512 | 3962,6 | 4097 | 0,26255 |
| 768 | 6405,6 | 6657 | 0,32736 |
| 1024 | 8947,2 | 9217 | 0,26352 |
| 1536 | 14345,0 | 14849 | 0,32801 |
| 2048 | 19940,0 | 20481 | 0,26401 |
| 3072 | 31760,0 | 32769 | 0,32833 |
| 4096 | 43974,0 | 45057 | 0,26426 |
| 6144 | 69662,0 | 71681 | 0,32849 |
| 8192 | 96139,0 | 98305 | 0,26438 |
| 12288 | 1,5161E5 | 155649 | 0,32857 |
| 16384 | 2,0866E5 | 212993 | 0,26444 |
| 24576 | 3,278E5 | 335873 | 0,32862 |
| 32768 | 4,5009E5 | 458753 | 0,26447 |
| 49152 | 7,0474E5 | 720897 | 0,32864 |
| 65536 | 9,6571E5 | 983041 | 0,26448 |
| 98304 | 1,5078E6 | 1540097 | 0,32865 |
| 131072 | 2,0625E6 | 2097153 | 0,26449 |
| 196608 | 3,2122E6 | 3276801 | 0,32865 |
| 262144 | 4,3871E6 | 4456449 | 0,26450 |
| 393216 | 6,8176E6 | 6946817 | 0,32865 |
| 524288 | 9,2985E6 | 9437185 | 0,26450 |
| 786432 | 1,4422E7 | 14680065 | 0,32865 |
| 1048576 | 1,9646E7 | 19922945 | 0,26450 |
| 1572864 | 3,0416E7 | 30932993 | 0,32866 |
| 2097152 | 4,1388E7 | 41943041 | 0,26450 |
| 3145728 | 6,3978E7 | 65011713 | 0,32866 |
| 4194304 | 8,6971E7 | 88080385 | 0,26450 |
| 6291456 | 1,3425E8 | 136314881 | 0,32866 |
| 8388608 | 1,8233E8 | 184549377 | 0,26450 |
| 12582912 | 2,8108E8 | 285212673 | 0,32866 |
| 16777216 | 3,8144E8 | 385875969 | 0,26450 |

## Korrektheit und Terminierung

Der Rekursionsabbruch stellt die Terminierung von Mergesort offensichtlich sicher, so dass lediglich noch die Korrektheit gezeigt werden muss. Dies geschieht, indem wir folgende Behauptung beweisen:
Behauptung: In Rekursionstiefe $i$ werden die sortierten Teillisten aus Rekursionstiefe $i{+}1$ korrekt sortiert.
Beweis: Sei o. B. d. A. die $(i{+}1)$-te Rekursion die tiefste. Dann sind die Teillisten offensichtlich sortiert, da sie einelementig sind. Somit ist ein Teil der Behauptung schon mal gesichert. Nun werden diese sortierten Teillisten eine Rekursionsebene nach oben, also in die $i$-te Rekursion übergeben. Dort werden diese nach Konstruktion der merge-Prozedur von Mergesort korrekt sortiert. Somit ist unsere Behauptung erfüllt und die totale Korrektheit von Mergesort bewiesen.

## Natural Mergesort

Natural Mergesort (natürliches Mergesort) ist eine Erweiterung von Mergesort, die bereits vorsortierte Teilfolgen, so genannte runs, innerhalb der zu sortierenden Startliste ausnutzt. Die Basis für den Mergevorgang bilden hier nicht die rekursiv oder iterativ gewonnenen Zweiergruppen, sondern die in einem ersten Durchgang zu bestimmenden runs:
Diese Variante hat den Vorteil, dass sortierte Folgen „erkannt“ werden und die Komplexität im Best-Case ${\mathcal {O}}(n)$ beträgt. Average- und Worst-Case-Verhalten ändern sich hingegen nicht.
Außerdem eignet sich Mergesort gut für größere Datenmengen, die nicht mehr im Hauptspeicher gehalten werden können – es müssen jeweils nur beim Verschmelzen in jeder Ebene zwei Listen vom externen Zwischenspeicher (z. B. Festplatte) gelesen und eine dorthin geschrieben werden. Eine Variante nutzt den verfügbaren Hauptspeicher besser aus (und minimiert Schreib-/Lesezugriffe auf der Festplatte), indem mehr als nur zwei Teil-Listen gleichzeitig vereinigt werden, und damit die Rekursionstiefe abnimmt.

## Paralleler Mergesort

Mergesort lässt sich aufgrund des Teile-und-herrsche Ansatzes gut parallelisieren. Verschiedene parallele Varianten wurden in der Vergangenheit entwickelt. Manche sind stark verwandt mit der hier vorgestellten sequentiellen Variante, während andere eine grundlegend verschiedene Struktur besitzen und das K-Wege-Mischen verwenden.

### Mergesort mit parallelen Rekursionsaufrufen

Der sequentielle Mergesort kann in zwei Phasen beschrieben werden, die Teilen-Phase und die anschließende Misch-Phase. Die erste besteht aus vielen rekursiven Aufrufen, die immer wieder den gleichen Aufteilungsprozess durchführen, bis die Teilsequenzen trivial sortiert sind (mit einem oder keinem Element). Ein intuitiver Ansatz ist es, diese rekursiven Aufrufe zu parallelisieren. Der folgende Pseudocode beschreibt den klassischen Mergesort Algorithmus mit paralleler Rekursion unter Verwendung der Schlüsselwörter fork and join.
Dieser Algorithmus ist die triviale Modifikation des sequentiellen Algorithmus und ist noch nicht optimal. Sein Speedup ist dementsprechend auch nicht beeindruckend. Er hat einen Spann von $\Theta (n)$, was nur eine Verbesserung um den Faktor $\Theta (\log n)$ ist im Vergleich zur sequentiellen Version. Dies liegt hauptsächlich an der sequentiellen Mischmethode, welche der Flaschenhals der parallelen Ausführung ist.

### Mergesort mit paralleler Mischmethode

Ein besserer Parallelismus kann durch eine parallele Mischmethode erreicht werden. Cormen et al. präsentieren eine binäre Variante, welche zwei sortierte Teilsequenzen in eine sortierte Ausgabesequenz mischt.
In der längeren der beiden Sequenzen (falls ungleich lang) wird das Element des mittleren Indexes ausgewählt. Seine Position in der anderen Sequenz wird so bestimmt, dass die Sequenz sortiert bliebe, wenn dieses Element an der bestimmten Stelle eingefügt werden würde. So weiß man, wie viele Elemente insgesamt kleiner sind als das Pivotelement, und die finale Position des Pivots kann in der Ausgabesequenz berechnet werden. Für die so erzeugten Teilfolgen der kleineren und größeren Elemente wird die Mischmethode wieder parallel ausgeführt, bis der Basisfall der Rekursion erreicht ist.
Der folgende Pseudocode illustriert den Mergesort mit modifizierter paralleler Mischmethode (aus Cormen et al.).
Um eine Rekurrenzrelation für den Worst Case zu erhalten, müssen die rekursiven Aufrufe von parallelMergesort aufgrund der parallelen Ausführung nur einmal aufgeführt werden. Man erhält
T$_∞$$^{sort}$(n)=T$_∞$$^{sort}$(n/2)+T$_∞$$^{merge}$(n)=T$_∞$$^{sort}$(n/2)+Θ(log⁡(n)$^2$){\textstyle T_{\infty }^{\text{sort}}(n)=T_{\infty }^{\text{sort}}\left({\frac {n}{2}}\right)+T_{\infty }^{\text{merge}}(n)=T_{\infty }^{\text{sort}}\left({\frac {n}{2}}\right)+\Theta \left(\log(n)^{2}\right)}.
Für genauere Informationen über die Komplexität der parallelen Mischmethode.
Die Lösung dieser Rekurrenz ist
T$_∞$$^{sort}$=Θ(log⁡(n)$^3$){\textstyle T_{\infty }^{\text{sort}}=\Theta \left(\log(n)^{3}\right)}.
Dieser Algorithmus erreicht eine Parallelisierbarkeit von $\Theta {\biggr{n \over (\log n)^{2}}{\biggr )}$, was um einiges besser ist als der Parallelismus des vorherigen Algorithmus. Solch ein Sortieralgorithmus kann, wenn er mit einem schnellen stabilen sequentiellen Sortieralgorithmus und einer sequentiellen Mischmethode als Basisfall für das Mischen von zwei kleinen Sequenzen ausgestattet ist, gut in der Praxis funktionieren.

### Paralleler Mehrwege-Mergesort

Es wirkt unnatürlich, Mergesort Algorithmen auf binäre Mischmethoden zu beschränken, da oftmals mehr als zwei Prozessoren zur Verfügung stehen. Ein besserer Ansatz wäre es, ein K-Wege-Mischen zu realisieren. Diese Generalisierung mischt im Gegensatz zum binären Mischen $k$ sortierte Sequenzen zu einer sortierten Sequenz. Diese Misch-Variante eignet sich gut zur Beschreibung eines Sortieralgorithmus auf einem PRAM.

#### Grundidee

Gegeben sei eine Folge von $n$ Elementen. Ziel ist es, diese Sequenz mit $p$ verfügbaren Prozessoren zu sortieren. Die Elemente sind dabei gleich auf alle Prozessoren aufgeteilt und werden zunächst lokal mit einem sequentiellen Sortieralgorithmus vorsortiert. Dementsprechend bestehen die Daten nun aus sortierten Folgen $S_{1},...,S_{p}$ der Länge ⌈ n/p ⌉{\textstyle \lceil {\frac {n}{p}}\rceil }. Der Einfachheit halber sei $n$ ein Vielfaches von $p$, so dass für $i=1,...,p$ gilt: |S$_i$|=n/p {\textstyle \left\vert S_{i}\right\vert ={\frac {n}{p}}}. Jede dieser Sequenzen wird wiederum in $p$ Teilsequenzen $S_{i,1},...,S_{i,p}$ partitioniert, indem für $j=1,...,p$ die Trennelemente $v_{j}$ mit globalem Rang k=j n/p {\textstyle k=j{\frac {n}{p}}} bestimmt werden. Die korrespondierenden Indizes werden in jeder Folge $S_{i}$ mit binärer Sucher ermittelt, sodass die Folgen anhand der Indizes aufgeteilt werden können. Formal definiert gilt somit $S_{i,j}:=\{x\in S_{i}|rank(v_{j-1})<rank(x)\leq rank(v_{j})\}$.
Nun werden die Elemente von $S_{1,i},...,S_{p,i}$ dem Prozessor $i$ zugeteilt. Dies sind alle Elemente vom globalen Rang (i−1) n/p {\textstyle (i-1){\frac {n}{p}}} bis zum Rang i n/p {\textstyle i{\frac {n}{p}}}, die über die $S_{i}$ verteilt sind. So erhält jeder Prozessor eine Folge von sortierten Sequenzen. Aus der Tatsache, dass der Rang $k$ der Trennelemente $v_{i}$ global gewählt wurde, ergeben sich zwei wichtige Eigenschaften: Zunächst sind die Trennelemente so gewählt, dass jeder Prozessor nach der Zuteilung der neuen Daten immer noch mit n/p{\textstyle n/p} Elementen betraut ist. Der Algorithmus besitzt also eine perfekte Lastverteilung. Außerdem sind alle Elemente des Prozessors $i$ kleiner oder gleich der Elemente des Prozessors $i+1$. Wenn nun jeder Prozessor ein p-Wege-Mischen lokal durchführt, sind aufgrund dieser Eigenschaft die Elemente global sortiert. Somit müssen die Ergebnisse nur in der Reihenfolge der Prozessoren zusammengesetzt werden.

#### Trennelementbestimmung

In der einfachsten Form sind $p$ sortierte Folgen $S_{1},...,S_{p}$ gleichverteilt auf $p$ Prozessoren sowie ein Rang $k$ gegeben. Gesucht ist nun ein Trennelement $x$ mit globalem Rang $k$ in der Vereinigung der Folgen. Damit kann jede Folge $S_{i}$ an einem Index $l_{i}$ in zwei Teile aufgeteilt werden: Der untere Teil besteht nur aus Elementen, die kleiner $x$ sind, während der obere Teil alle Elemente enthält, welche größer oder gleich als $x$ sind.
Der hier vorgestellte sequentielle Algorithmus gibt die Indizes der Trennungen zurück, also die Indizes $l_{i}$in den Folgen $S_{i}$, sodass $S_{i}[l_{i}]$ einen global kleineren Rang als $k$ hat und $\mathrm {rank} \left(S_{i}[l_{i}+1]\right)\geq k$ ist.
Für die Komplexitätsanalyse wurde das PRAM-Modell gewählt. Die p-fache Ausführung der binarySearch Methode hat eine Laufzeit in ${\mathcal {O}}\left(p\log \left(n/p\right)\right)$, falls die Daten über alle $p$ Prozessoren gleichverteilt anliegen. Die erwartete Rekursionstiefe beträgt wie im Quickselect Algorithmus ${\mathcal {O}}\left(\log \left(\textstyle \sum _{i}|S_{i}|\right)\right)={\mathcal {O}}(\log(n))$. Somit ist die gesamte erwartete Laufzeit ${\mathcal {O}}\left(p\log(n/p)\log(n)\right)$.
Angewandt auf den parallelen Mehrwege-Mergesort muss die msSelect Methode parallel ausgeführt werden, um alle Trennelemente vom Rang i n/p {\textstyle i{\frac {n}{p}}} gleichzeitig zu finden. Dies kann anschließend verwendet werden, um jede Folge in $p$ Teile zu zerschneiden. Es ergibt sich die gleiche Gesamtlaufzeit ${\mathcal {O}}\left(p\,\log(n/p)\log(n)\right)$.

#### Pseudocode

Hier ist der komplette Pseudocode für den parallelen Mehrwege-Mergesort. Dabei wird eine Barriere-Synchronisation vor und nach der Trennelementbestimmung angenommen, sodass jeder Prozessor seine Trennelemente und die Partitionierung seiner Sequenz richtig berechnen kann.

#### Analyse

Zunächst sortiert jeder Prozessor die zugewiesenen $n/p$ Elemente lokal mit einem vergleichsbasierten Sortieralgorithmus der Komplexität ${\mathcal {O}}\left(n/p\;\log(n/p)\right)$. Anschließend können die Trennelemente in Zeit ${\mathcal {O}}\left(p\,\log(n/p)\log(n)\right)$ bestimmt werden. Schließlich müssen jede Gruppe von $p$ Teilstücken gleichzeitig von jedem Prozessor zusammen gemischt werden. Dies hat eine Laufzeit von ${\mathcal {O}}(\log(p)\;n/p)$, indem ein sequentieller k-Wege Mischalgorithmus verwendet wird. Somit ergibt sich eine Gesamtlaufzeit von
${\mathcal {O}}\left({\frac {n}{p}}\log \left({\frac {n}{p}}\right)+p\log \left({\frac {n}{p}}\right)\log(n)+{\frac {n}{p}}\log(p)\right)$.

#### Praktische Anpassung und Anwendung

Der Mehrwege-Mergesort Algorithmus ist durch seine hohe Parallelität, was den Einsatz vieler Prozessoren ermöglicht, sehr skalierbar. Dies macht den Algorithmus zu einem brauchbaren Kandidaten für das Sortieren großer Datenmengen, wie sie beispielsweise in Computer-Clustern verarbeitet werden. Da der Speicher in solchen Systemen in der Regel keine limitierende Ressource darstellt, ist der Nachteil der Speicherkomplexität von Mergesort vernachlässigbar. Allerdings werden in solchen Systemen andere Faktoren wichtig, die bei der Modellierung auf einer PRAM nicht berücksichtigt werden. Hier sind unter anderem die folgenden Aspekte zu berücksichtigen: Die Speicherhierarchie, wenn die Daten nicht in den Cache der Prozessoren passen, oder der Kommunikationsaufwand beim Datenaustausch zwischen den Prozessoren, der zu einem Engpass werden könnte, wenn auf die Daten nicht mehr über den gemeinsamen Speicher zugegriffen werden kann.
Sanders et al. haben in ihrem Paper einen bulk synchronous parallel-Algorithmus für einen mehrstufigen Mehrwege-Mergesort vorgestellt, der $p$ Prozessoren in $r$ Gruppen der Größe $p'$ unterteilt. Alle Prozessoren sortieren zuerst lokal. Im Gegensatz zu einem einstufigen Mehrwege-Mergesort werden diese Sequenzen dann in $r$ Teile aufgeteilt und den entsprechenden Prozessorgruppen zugeordnet. Diese Schritte werden innerhalb dieser Gruppen rekursiv wiederholt. So wird die Kommunikation reduziert und insbesondere Probleme mit vielen kleinen Nachrichten vermieden. Die hierarchische Struktur des zugrundeliegenden realen Netzwerks (z. B. Racks, Cluster,...) kann zur Definition der Prozessorgruppen verwendet werden.

### Weitere Varianten

Mergesort war einer der ersten Sortieralgorithmen, bei dem ein optimaler Speedup erreicht wurde, wobei Richard Cole einen cleveren Subsampling-Algorithmus verwendete, um die O(1)-Zusammenführung sicherzustellen. Andere ausgeklügelte parallele Sortieralgorithmen können die gleichen oder bessere Zeitschranken mit einer niedrigeren Konstante erreichen. David Powers beschrieb beispielsweise 1991 einen parallelisierten Quicksort (und einen verwandten Radixsort), der durch implizite Partitionierung in $O(\log n)$ Zeit auf einer CRCW-Parallel Random Access Machine (PRAM) mit $n$ Prozessoren arbeiten kann. Powers zeigt ferner, dass eine Pipeline-Version von Batchers Bitonic Mergesort in $O((\log n)^{2})$ Zeit auf einem Butterfly-Sortiernetzwerk in der Praxis schneller ist als sein $O(\log n)$ Sortieralgorithmus auf einer PRAM, und er bietet eine detaillierte Diskussion der versteckten Overheads beim Vergleich, bei der Radix- und der Parallelsortierung.

## Sonstiges

Da Mergesort die Startliste sowie alle Zwischenlisten sequenziell abarbeitet, eignet er sich besonders zur Sortierung von verketteten Listen. Für Arrays wird normalerweise ein temporäres Array derselben Länge des zu sortierenden Arrays als Zwischenspeicher verwendet (das heißt Mergesort arbeitet normalerweise nicht in-place, s. o.). Quicksort dagegen benötigt kein temporäres Array.
Für die Größe des temporären Arrays reicht die halbe Größe der Anzahl der Elemente (n/2) aus. Unoptimierte Codebeispiele arbeiten mit einem Hilfsarray der Größe (n), dies ist für den Mergesort Algorithmus nicht erforderlich.
Die SGI-Implementierung der Standard Template Library (STL) verwendet den Mergesort als Algorithmus zur stabilen Sortierung.