Informatik

Mergesort einfach erklärt: Ablauf und Laufzeit

Mergesort einfach erklärt: Ablauf und Laufzeit

Mergesort einfach erklärt: Ablauf und Laufzeit
Mergesort einfach erklärt: Ablauf und Laufzeit
Für Quiz, Lückentext, Lernkarten und Fortschritt ist JavaScript nötig. Alle Inhalte und Lösungen bleiben direkt lesbar.

Mergesort sortiert eine Folge, indem er sie wiederholt halbiert und die sortierten Teile anschließend wieder zusammenführt. Dieses Teile-und-herrsche-Verfahren erreicht bei klassischen Implementierungen stets die Laufzeit $O(n \log n)$.

Hier betrachten wir die klassische rekursive Array-Variante ohne Abkürzung für bereits sortierte Bereiche. Ein Array speichert Elemente auf nummerierten Plätzen; in den Beispielen sortierst du Zahlen aufsteigend.

Deine Lernziele

Hake ab, was du schon kannst — und komm am Ende hierher zurück!

Der Ablauf in drei Schritten

Stell dir vor, du sollst viele ungeordnete Zahlen sortieren. Mergesort löst nicht sofort die ganze Aufgabe, sondern zerlegt sie in immer kleinere Aufgaben.

Definition

Teile-und-herrsche

Ein Teile-und-herrsche-Verfahren zerlegt ein Problem in kleinere Teilprobleme, löst diese und verbindet ihre Lösungen zu einer Gesamtlösung.

Mergesort arbeitet in drei Schritten:

  1. Teilen: Halbiere die Folge ungefähr in eine linke und eine rechte Hälfte.
  2. Sortieren: Sortiere beide Hälften auf dieselbe Weise. Folgen mit höchstens einem Element sind bereits sortiert.
  3. Verschmelzen: Führe die beiden sortierten Hälften zu einer sortierten Folge zusammen.

Der zweite Schritt ruft dasselbe Verfahren für kleinere Folgen auf. Das nennt man Rekursion. Der Abbruch bei höchstens einem Element verhindert, dass immer weiter geteilt wird.

Merke

Mergesort teilt bis zu Einzelelementen. Die eigentliche Sortierarbeit geschieht beim anschließenden Verschmelzen.

Teste dich
Frage 1 von 1LeichtWann endet die rekursive Teilungsphase?
Lösung: Wenn eine Teilfolge höchstens ein Element enthält — Eine leere oder einelementige Folge ist bereits sortiert und muss nicht weiter zerlegt werden.
So verschmilzt du zwei sortierte Folgen

Beim Merge-Schritt liegen bereits zwei sortierte Folgen vor. Du vergleichst jeweils ihre ersten noch nicht übernommenen Elemente.

So gehst du vor:

  1. Vergleiche das nächste Element der linken mit dem nächsten Element der rechten Folge.
  2. Übernimm das kleinere Element in die Ergebnisfolge; bei Gleichheit das linke.
  3. Rücke nur in der Folge weiter, aus der du das Element genommen hast.
  4. Wiederhole den Vergleich, bis eine Folge leer ist.
  5. Hänge den unverarbeiteten Rest der anderen Folge an.
Beispiel

Verschmelze [2, 3, 5] und [1, 4, 6]:

  • Vergleiche 2 und 1: Übernimm 1.
  • Vergleiche 2 und 4: Übernimm 2.
  • Vergleiche 3 und 4: Übernimm 3.
  • Vergleiche 5 und 4: Übernimm 4.
  • Vergleiche 5 und 6: Übernimm 5.
  • Die linke Folge ist leer. Hänge den Rest 6 an.

Das Ergebnis ist [1, 2, 3, 4, 5, 6].

Gleiche Schlüssel stabil behandeln

Der Sortierschlüssel ist der Wert, nach dem du ordnest. Ein Sortierverfahren heißt stabil, wenn Einträge mit gleichem Schlüssel ihre ursprüngliche Reihenfolge behalten. In 2_A und 2_B ist jeweils 2 der Schlüssel; die Buchstaben unterscheiden die Einträge. Beim Teilen bleiben die ursprüngliche Reihenfolge und die Zuordnung zur linken oder rechten Hälfte erhalten.

Angenommen, 2_A stand vor 2_B. Beim Merge von [2_A, 5] und [2_B, 4] muss bei Gleichheit das linke Element 2_A zuerst übernommen werden. Das Ergebnis beginnt dann mit [2_A, 2_B, ...].

In einer Bedingung wird deshalb links gewählt, wenn links <= rechts gilt. Eine Bedingung mit nur < würde bei Gleichheit rechts wählen und die Stabilität gefährden.

Teste dich
Frage 1 von 1MittelWelches Element wird beim stabilen Merge von [3_A, 7] und [3_B, 5] zuerst übernommen?
Lösung: 3_A aus der linken Folge — Bei Gleichheit bewahrt „links zuerst“ die ursprüngliche Reihenfolge gleicher Schlüssel.
Ein vollständiger Sortierdurchlauf

Sortiere nun [7, 2, 6, 3, 8, 1, 5, 4].

Teilen

  • [7, 2, 6, 3] und [8, 1, 5, 4]
  • [7, 2], [6, 3], [8, 1], [5, 4]
  • [7], [2], [6], [3], [8], [1], [5], [4]

Jede entstandene Einzelfolge ist sortiert.

Paarweise verschmelzen

  • [7] und [2] werden zu [2, 7].
  • [6] und [3] werden zu [3, 6].
  • [8] und [1] werden zu [1, 8].
  • [5] und [4] werden zu [4, 5].

Danach entstehen größere sortierte Folgen:

  • [2, 7] und [3, 6] werden zu [2, 3, 6, 7].
  • [1, 8] und [4, 5] werden zu [1, 4, 5, 8].

Im letzten Merge werden diese beiden Folgen zu [1, 2, 3, 4, 5, 6, 7, 8] verbunden.

Gut zu wissen

Beim Teilen wird noch kein Element an eine andere Position sortiert. Die Reihenfolge ändert sich erst durch die Merge-Schritte auf dem Rückweg der Rekursion.

Teste dich
Frage 1 von 1MittelWelche Folgen werden unmittelbar vor dem letzten Merge miteinander verbunden?
Lösung: [2, 3, 6, 7] und [1, 4, 5, 8] — Unmittelbar vor dem letzten Schritt müssen beide Hälften bereits vollständig sortiert sein.
Warum das Ergebnis korrekt sortiert ist

Für die Korrektheit begründest du, dass das Ergebnis sortiert ist, alle Eingabeelemente genau einmal enthält und das Verfahren endet.

Warum der Merge-Schritt stimmt

Eine Invariante ist eine Aussage, die vor und nach jedem Schleifendurchlauf gilt. Beim Merge ist die bisherige Ergebnisfolge sortiert, und keines ihrer Elemente ist größer als ein noch unverarbeitetes Element. Zu Beginn gilt das für die leere Ergebnisfolge.

Das nächste Ergebnis kann nur eines der beiden vordersten unverarbeiteten Elemente sein. Alle späteren Elemente derselben Folge sind mindestens ebenso groß. Wenn du das kleinere der beiden Vorderseiten wählst, bleibt die Ergebnisfolge deshalb sortiert.

Ist eine Eingabefolge leer, darf der sortierte Rest der anderen angehängt werden: Er ist laut Invariante nicht kleiner als die bisherigen Ergebnisse. Jedes Element wird genau einmal übernommen; keines geht verloren oder wird verdoppelt.

Warum die Rekursion stimmt

  • Folgen mit höchstens einem Element sind sortiert.
  • Jeder rekursive Aufruf arbeitet mit einer kleineren Folge und erreicht daher den Abbruchfall.
  • Sind die beiden kleineren Ergebnisse sortiert, erzeugt der korrekte Merge daraus wieder eine sortierte Folge.

So entsteht von den Einzelfolgen bis zur Gesamtfolge auf jeder Ebene ein korrekt sortiertes Ergebnis.

Teste dich
Frage 1 von 1MittelWarum darf der Rest einer Folge ohne weitere Schlüsselvergleiche angehängt werden?
Lösung: Die andere Folge ist leer, und der Rest ist bereits in sich sortiert. — Sobald eine Seite leer ist, existiert dort kein konkurrierendes Element mehr. Der verbleibende Rest ist bereits sortiert.
Laufzeit und Speicherbedarf begründen

Dabei bezeichnet $n$ die Anzahl der Elemente. Wir rechnen für einen Schlüsselvergleich und für das Kopieren eines Elements jeweils mit konstantem Aufwand. Lineare Arbeit wächst proportional zu $n$; die O-Notation beschreibt eine obere Wachstumsschranke und lässt konstante Faktoren weg.

Für $n \ge 2$ entstehen ungefähr $\log_2 n$ Teilungsebenen. Der Logarithmus zählt hier, wie oft du halbierst, bis die Teilfolgen höchstens ein Element enthalten. Für Zweierpotenzen ist die Ebenenzahl genau $\log_2 n$.

Auf jeder Merge-Ebene werden insgesamt höchstens $n$ Elemente verarbeitet; bei Zweierpotenzen sind es genau $n$. Lineare Arbeit je Ebene und logarithmisch viele Ebenen ergeben:

$$O(n \log n)$$

Für acht Elemente gibt es drei Teilungsebenen, weil wiederholt 8, 4, 2, 1 Elemente pro Teilfolge auftreten. Im vereinfachten Ebenenmodell ergibt das $8 \cdot 3 = 24$ Verarbeitungseinheiten. Diese Zahl veranschaulicht das Wachstum; sie ist keine gemessene Laufzeit.

Best Case meint den günstigsten, Worst Case den ungünstigsten Fall bei gleicher Eingabelänge; Average Case den Durchschnitt bei einer festgelegten Verteilung der Eingaben. Klassischer Mergesort bleibt bei zufälligen, aufsteigend und absteigend angeordneten Eingaben asymptotisch in $O(n \log n)$. Konkrete Laufzeiten und Vergleichszahlen können sich trotzdem unterscheiden.

Beim Merge zweier nicht leerer Folgen mit $a$ und $b$ Elementen sind höchstens $a+b-1$ Schlüsselvergleiche nötig: Nach so vielen Übernahmen bleibt nur ein Element übrig, sodass eine Seite leer sein muss. War eine Folge schon anfangs leer, sind keine Schlüsselvergleiche nötig.

Zusätzlicher Speicher

Eine übliche Array-Implementierung schreibt Merge-Ergebnisse in ein Hilfsarray. Dafür wird zusätzlicher Speicher der Größenordnung

$$O(n)$$

benötigt. Standard-Mergesort für Arrays arbeitet daher normalerweise nicht in-place, also nicht nur innerhalb des ursprünglichen Arrays mit konstantem Zusatzspeicher.

Teste dich
Frage 1 von 2LeichtWelche asymptotische Laufzeit hat klassischer Mergesort im Worst Case?
Lösung: $O(n \log n)$ — Es gibt logarithmisch viele Ebenen, auf denen jeweils insgesamt linear viele Elemente verarbeitet werden.
Frage 2 von 2MittelWarum reicht „Der Merge-Schritt ist linear“ allein noch nicht als Laufzeitanalyse des gesamten Verfahrens?
Lösung: Weil Merge-Arbeit auf ungefähr $\log_2 n$ Ebenen anfällt — Für die Gesamtlaufzeit müssen sowohl die Arbeit pro Ebene als auch die Zahl der Ebenen berücksichtigt werden.
Wann Mergesort gut passt

Die asymptotische Laufzeit ist nicht das einzige Auswahlkriterium. Prüfe auch Stabilität, Speicher, Vorsortierung und die verwendete Datenstruktur.

SituationEinordnung
Gleiche Schlüssel sollen ihre Reihenfolge behaltenStabil implementierter Mergesort passt gut.
Eine garantierte Worst-Case-Laufzeit von $O(n \log n)$ ist wichtigMergesort bietet diese Schranke.
Für ein Array steht kaum Zusatzspeicher bereitStandard-Mergesort ist wegen $O(n)$ Hilfsspeicher ungünstig.
Die Daten sind größer als der HauptspeicherSequentielles Verschmelzen macht Mergesort für externe Sortierung geeignet.
Die Eingabe enthält lange vorsortierte BereicheNatural Mergesort kann diese Bereiche direkt nutzen.

Natural Mergesort

Runs sind hier möglichst lange zusammenhängende, nicht absteigend sortierte Abschnitte: Gleiche Nachbarwerte sind erlaubt. Ein neuer Run beginnt, wenn der nächste Wert kleiner als sein Vorgänger ist. Natural Mergesort erkennt diese Runs und verschmilzt in jeder Runde benachbarte Paare. Ein einzelner übrig gebliebener Run wird in die nächste Runde übernommen.

In der Folge [3, 4, 2, 1, 7, 5, 8, 9, 0, 6] sind beispielsweise die Runs [3, 4], [2], [1, 7], [5, 8, 9] und [0, 6] enthalten.

Eine vollständig aufsteigend sortierte Folge bildet nur einen Run. Natural Mergesort kann diesen Fall in $O(n)$ erkennen. Bei paarweisen Merge-Runden bleibt die Laufzeit im schlechtesten Fall in $O(n \log n)$, weil sich die Zahl der Runs pro Runde ungefähr halbiert.

In-place ist nicht automatisch schneller

Es gibt In-place-Varianten von Mergesort. Eine einfache Variante schafft Platz durch wiederholtes Verschieben von Arrayelementen. Bei insgesamt $n$ Elementen kann ein solcher Merge im schlechtesten Fall quadratische Arbeit, also $O(n^2)$, benötigen: Viele rechte Elemente müssen jeweils an vielen linken vorbeigeschoben werden. Weniger Zusatzspeicher kann also mit deutlich mehr Laufzeit bezahlt werden.

Teste dich
Frage 1 von 2MittelFiktives Beispiel: Ein Archiv soll sehr viele Datensätze stabil sortieren, die nicht vollständig in den Hauptspeicher passen. Welche Eigenschaft spricht für Mergesort?
Lösung: Die Daten können beim Verschmelzen weitgehend sequenziell verarbeitet werden. — Mergesort eignet sich für externe Sortierung, weil sortierte Teilfolgen nacheinander gelesen und zusammengeführt werden können.
Frage 2 von 2SchwerEine sehr lange Folge ist bereits vollständig aufsteigend sortiert. Welche Variante kann diese Struktur unmittelbar ausnutzen?
Lösung: Natural Mergesort durch Erkennen eines einzigen Runs — Natural Mergesort erkennt vorhandene sortierte Abschnitte und kann den vollständig sortierten Fall in $O(n)$ bearbeiten.
Karteikasten
Karteikasten

Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.

Alles auf einen Blick
Mindmap
  • Mergesort
    • Teilen: ungefähr halbieren bis zu Einzelfolgen
    • Verschmelzen: kleinere Vorderseite übernehmen, Rest anhängen
    • Korrektheit: Abbruchfall und korrekter Merge tragen jede Ebene
    • Stabilität: bei Gleichheit das linke Element zuerst wählen
    • Laufzeit: lineare Arbeit auf logarithmisch vielen Ebenen
    • Speicher: Standard-Array-Variante benötigt linearen Hilfsspeicher
    • Natural Mergesort: vorhandene Runs erkennen und nutzen
    • Auswahl: Laufzeitgarantie, Stabilität, Speicher und Eingabe prüfen
Abschluss-Check
Teste dich
Frage 1 von 3LeichtWelche Aussage beschreibt Mergesort korrekt?
Lösung: Die Folge wird geteilt, die Teilfolgen werden sortiert und anschließend verschmolzen. — Mergesort verbindet rekursives Teilen mit dem geordneten Verschmelzen sortierter Teilfolgen.
Frage 2 von 3MittelBeim Merge stehen links [2_A, 6] und rechts [2_B, 4]. Welche Ausgabe beginnt einen stabilen Merge korrekt?
Lösung: [2_A, 2_B, ...] — Die Reihenfolge gleicher Schlüssel bleibt nur erhalten, wenn bei Gleichheit links bevorzugt wird.
Frage 3 von 3SchwerDu brauchst für ein Array eine garantierte Laufzeit von $O(n \log n)$ und eine stabile Sortierung; linearer Hilfsspeicher ist verfügbar. Welche Entscheidung ist nachvollziehbar?
Lösung: Verwende einen stabil implementierten Mergesort. — Mergesort erfüllt die Laufzeitgarantie und kann stabil arbeiten. Der verfügbare Hilfsspeicher deckt seinen typischen Nachteil bei Arrays ab.

Du beherrschst Mergesort, wenn du den Weg von den Einzelfolgen bis zum Endergebnis erklären, den Merge selbst ausführen und die Wahl des Verfahrens mit Laufzeit, Stabilität und Speicher begründen kannst.

Passend dazu

9 Kapitel

Kapitel 1