Sorteren 2: mergesort en quicksort
Een miljoen waarden sorteren door elk paar te vergelijken kost ongeveer 500 miljard vergelijkingen; mergesort heeft er ongeveer 20 miljoen nodig.
Splits het probleem en los de helften op
De methoden uit het vorige hoofdstuk werken op de hele lijst tegelijk en betalen daarvoor ongeveer n² vergelijkingen. De twee methoden hier gebruiken een ander plan, verdeel en heers. Splits de lijst in kleinere delen, sorteer elk deel met dezelfde methode en combineer de gesorteerde delen. Het splitsen gaat door tot een deel één waarde of geen heeft; een lijst van één waarde is al gesorteerd. Omdat de methode zichzelf aanroept op kleinere lijsten, is zij recursief (in hoofdstuk 6 bekijk je recursie in detail).
Mergesort: het werk zit in het samenvoegen
Mergesort deelt de lijst doormidden, sorteert de linkerhelft, sorteert de rechterhelft en voegt beide gesorteerde helften samen. Het slimme deel is het samenvoegen. Twee gesorteerde lijsten kun je combineren door alleen hun voorste waarden te bekijken. Vergelijk die, schrijf de kleinste op en schuif daar voorbij. Herhaal tot één lijst leeg is en kopieer dan de rest van de andere. [1, 4, 7] en [2, 3, 8] samenvoegen gaat als 1 (1 tegenover 2), 2 (4 tegenover 2), 3 (4 tegenover 3), 4 (4 tegenover 8), 7 (7 tegenover 8), waarna 8 wordt gekopieerd: 5 vergelijkingen voor 6 waarden. Twee lijsten met samen n waarden samenvoegen kost nooit meer dan n − 1 vergelijkingen.
function merge(left, right) {
const out = [];
let i = 0, j = 0;
while (i < left.length && j < right.length) {
if (right[j] < left[i]) out.push(right[j++]);
else out.push(left[i++]);
}
return out.concat(left.slice(i), right.slice(j));
}
function mergeSort(a) {
if (a.length <= 1) return a; // already sorted
const mid = Math.floor(a.length / 2);
return merge(mergeSort(a.slice(0, mid)), mergeSort(a.slice(mid)));
}Waarom is dit snel? Stel je het halveren voor als niveaus. Een lijst van 8 waarden splitst in 2 lijsten van 4, dan 4 lijsten van 2 en dan 8 lijsten van 1: drie niveaus, want 8 kan 3 keer worden gehalveerd. Op elk niveau raken alle samenvoegingen samen elke waarde eenmaal, dus een niveau kost hoogstens ongeveer n vergelijkingen. Met log₂ n niveaus is het totaal ongeveer n log₂ n. Voor een miljoen waarden zijn dat ongeveer 20 miljoen vergelijkingen, tegenover ongeveer 500 miljard voor de methoden die elk paar vergelijken. Gesplitst als [38, 27, 43, 3] en [9, 82, 10], zoals in het lab, kost [38, 27, 43, 3, 9, 82, 10] 14 vergelijkingen; de code hierboven splitst in 3 en 4 en kost 13.
De prijs is geheugen. Samenvoegen vraagt een plek om de uitvoer te schrijven, dus mergesort gebruikt een tweede lijst zo groot als de invoer. Mergesort is ook stabiel: waarden die gelijk vergelijken behouden hun oorspronkelijke volgorde, omdat bij gelijke voorste waarden de linker wordt genomen. Dat is belangrijk als je een tabel achtereenvolgens op verschillende kolommen sorteert, bijvoorbeeld op stad en dan op naam.
Sleep om te draaien. Scroll of knijp om te zoomen.
Quicksort: splits rond een spil
Quicksort verdeelt de lijst anders. Het kiest één waarde, de spil, en herschikt de lijst zodat alles kleiner dan de spil ervoor komt en de rest erna. Deze stap heet partitioneren. De spil staat nu definitief goed en beide kanten kun je afzonderlijk met dezelfde methode sorteren. Achteraf samenvoegen is niet nodig, omdat elke waarde links al kleiner is dan elke waarde rechts.
In het lab gebruik je een gangbare leerboekversie die de laatste waarde van elk deel als spil neemt. Op [5, 1, 4, 2, 8] wordt spil 8 met de vier andere, kleinere waarden vergeleken, dus 8 blijft achteraan. Het volgende deel [5, 1, 4, 2] gebruikt spil 2: alleen 1 is kleiner, dus na twee verwisselingen is de lijst [1, 2, 4, 5, 8]. Nog één vergelijking verwerkt [4, 5]. Totaal: 8 vergelijkingen en 2 verwisselingen.
Als de spil dicht bij het midden uitkomt, halveert elke splitsing het probleem en kost quicksort ongeveer n log₂ n vergelijkingen, net als mergesort. Het werkt ook binnen de oorspronkelijke lijst zonder tweede kopie. Maar een slechte spil schaadt. Als de lijst al gesorteerd is en de spil altijd de laatste waarde, haalt elke splitsing slechts één waarde weg en valt quicksort terug op ongeveer n²/2 vergelijkingen: 10 voor [1, 2, 3, 4, 5], hetzelfde als selectionsort. Echte bibliotheken vermijden dit door de spil zorgvuldiger te kiezen, bijvoorbeeld willekeurig of als middelste van drie steekproefwaarden.
| Methode | Vergelijkingen | Extra geheugen |
|---|---|---|
| Insertionsort | gebruikelijk ongeveer n²/4, slechtste geval ongeveer n²/2 | geen; stabiel |
| Mergesort | altijd ongeveer n log₂ n | een tweede lijst van n waarden; stabiel |
| Quicksort | gebruikelijk ongeveer n log₂ n, slechtste geval ongeveer n²/2 (slechte spillen) | weinig; gebruikelijke versies niet stabiel |
| verdeel en heers | Splits een probleem, los de delen op dezelfde manier op en combineer de resultaten |
| samenvoegen | Combineer twee gesorteerde lijsten door steeds de kleinste voorste waarde te nemen |
| mergesort | Halveer, sorteer elke helft, voeg samen: ongeveer n log₂ n vergelijkingen |
| spil | De waarde waar quicksort de lijst omheen splitst |
| partitioneren | Herschikken zodat kleinere waarden vóór de spil staan en de rest erna |
| quicksort | Partitioneer rond een spil en sorteer dan elke kant |
| stabiele sortering | Gelijke waarden behouden hun oorspronkelijke volgorde |
| ter plekke | Sorteert binnen de oorspronkelijke lijst met weinig extra geheugen |
- Hoeveel vergelijkingen kost het om [1, 4, 7] en [2, 3, 8] samen te voegen?
- Hoeveel vergelijkingen kost het om [1, 2, 3] en [4, 5, 6] samen te voegen?
- Een lijst van 16 waarden wordt gehalveerd totdat elk deel één waarde heeft. Hoeveel halveringsniveaus zijn er?
- Hoeveel vergelijkingen doet mergesort ongeveer op een miljoen waarden?
- ongeveer 20
- ongeveer 20 miljoen
- ongeveer 500 miljard
- precies één miljoen
- Waar staat de spil na het partitioneren?
- Op de definitieve gesorteerde positie
- Vooraan
- Achteraan
- Ergens; hij beweegt later opnieuw
- Quicksort met de laatste waarde als spil werkt op de al gesorteerde lijst [1, 2, 3, 4, 5]. Hoeveel vergelijkingen doet het?
- Welke methode heeft een tweede lijst zo groot als de invoer nodig?
- Mergesort
- Quicksort
- Insertionsort
- Wie stelde mergesort in 1945 voor?
- Tony Hoare
- John von Neumann
- Ada Lovelace
- Euclides
- Welk probleem bracht Tony Hoare tot quicksort?
- Woorden van een zin sorteren voor een woordenboek op magneetband
- Bibliotheekboeken sorteren
- Webpagina's rangschikken
- Bankcheques sorteren
- Waarom heet mergesort stabiel?
- Gelijke waarden behouden hun oorspronkelijke volgorde
- Het loopt nooit vast
- Het kost altijd evenveel tijd
- Het gebruikt geen extra geheugen
- Wat is het kleinste mogelijke maximale aantal vergelijkingen voor een vergelijkingssorteermethode op 10 waarden (log₂ 10!, naar boven afgerond)?
- Verdeel en heers: splits, los de delen op, combineer.
- Mergesort: altijd ongeveer n log₂ n vergelijkingen, extra geheugen nodig, stabiel.
- Quicksort: partitioneer rond een spil; gemiddeld snel, ongeveer n²/2 met slechte spillen.
- Een miljoen waarden: ongeveer 20 miljoen vergelijkingen in plaats van 500 miljard.
- Geen vergelijkingssorteermethode kan in het slechtste geval beter dan ongeveer n log₂ n.
Bronnen van deze cursus (11)
- MIT OpenCourseWare 6.006 Introduction to Algorithms, Spring 2020 (Demaine, Ku, Solomon)
- lecture notes 1 Introduction, 3 Sorting, 9 Breadth-First Search, 10 Depth-First Search (ocw.mit.edu/courses/6-006-introduction-to-algorithms-spring-2020/pages/lecture-notes) and Fall 2011 lecture 13 BFS notes (ocw.mit.edu/courses/6-006-introduction-to-algorithms-fall-2011)
- Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms (MIT Press)
- with the CLRS-based Khan Academy algorithms unit by Thomas Cormen and Devin Balkcom of Dartmouth (khanacademy.org/computing/computer-science/algorithms: binary search, selection sort analysis, merge sort, quicksort overview and analysis)
- MacTutor History of Mathematics, Al-Khwarizmi (mathshistory.st-andrews.ac.uk/Biographies/Al-Khwarizmi: word algorithm from the Latin title Algoritmi de numero Indorum)
- D. E. Joyce, Euclid's Elements Book VII Propositions 1 and 2 (mathcs.clarku.edu/~djoyce/elements/bookVII)
- Wolfram MathWorld, Merge Sort (mathworld.wolfram.com/MergeSort.html: proposed by John von Neumann in 1945, after Knuth 1998 p. 159)
- Stanford CS "Tony Hoare: Quicksort" (cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/tony-hoare/quicksort.html: devised while a student at Moscow State University for Russian-English machine translation with a tape dictionary, programmed in Algol 60 and published 1961; the year 1959 from the Wikipedia Quicksort article and its cited sources)
- Bodleian Libraries, Ada Lovelace (blogs.bodleian.ox.ac.uk/adalovelace: 1843 paper, Note G Bernoulli numbers)
- Fourmilab text of Menabrea's Sketch with Lovelace's notes (fourmilab.ch/babbage/sketch.html)
- Seven Bridges of Konigsberg (Euler 1736) and Tower of Hanoi (Edouard Lucas, 1883) checked against the Wikipedia articles and their cited sources.
Geraadpleegd: 2026-10-17