Quicksort: definitie en werking van het snelle verdeel-en-heers sorteeralgoritme
Ontdek Quicksort: snelle uitleg, werking, partities, complexiteit en praktische voorbeelden van het efficiënte verdeel-en-heers sorteeralgoritme.
Quicksort is een sorteeralgoritme dat veel gebruikt wordt om elementen in een array te sorteren. Het is bedacht door Tony Hoare in 1959. Quicksort is een verdeel-en-heers (divide-and-conquer) algoritme: het splitst de array in delen (partities) rondom een gekozen pivot, sorteert die delen vervolgens onafhankelijk en combineert de resultaten door eenvoudigweg de onderdelen achter elkaar te zetten. Omdat Quicksort gebruikmaakt van vergelijkingen tussen elementen valt het in de categorie van vergelijkingssorteringen.
Afbeeldingengalerij
3 AfbeeldingenWerking in eenvoudige stappen
- Kies een pivot: selecteer één element uit de array (bijv. het eerste, laatste, middelste, of een willekeurig element).
- Partitioneer: herschik de array zo dat alle elementen kleiner dan de pivot links staan en alle elementen groter dan de pivot rechts (elementen gelijk aan de pivot kunnen links, rechts of tussenin komen, afhankelijk van de partitiemethode).
- Herhaal recursief: pas Quicksort toe op de linker- en rechterdeelarrays totdat elk deel triviaal (lengte 0 of 1) is.
Partitioneringsmethoden
Er bestaan meerdere varianten om te partitioneren. Twee veelgebruikte zijn:
- Lomuto-partitie (eenvoudig te implementeren, maar soms minder efficiënt): kiest vaak het laatste element als pivot en loopt met één index door de array om elementen kleiner dan de pivot naar links te verplaatsen.
- Hoare-partitie (origineel van Hoare): gebruikt twee aanwijzers van beide kanten en is doorgaans iets efficiënter en doet minder swaps in de praktijk.
Naast deze basismethoden bestaan er varianten zoals three-way partitioning (Dijkstra's Dutch National Flag) die handig is wanneer veel dubbele waarden aanwezig zijn: dan wordt in één stap verdeeld in kleiner, gelijk en groter dan pivot.
Voorbeeldpseudocode (kort)
Lomuto-partitie (vereenvoudigd):
function partition(A, lo, hi): pivot = A[hi] i = lo for j from lo to hi-1: if A[j] <= pivot: swap A[i], A[j] i = i + 1 swap A[i], A[hi] return i
Quicksort (recursief):
function quicksort(A, lo, hi): if lo < hi: p = partition(A, lo, hi) quicksort(A, lo, p-1) quicksort(A, p+1, hi)
Tijd- en ruimtecomplexiteit
- Gemiddelde tijdcomplexiteit: O(n log n) — dit verklaart waarom Quicksort in de praktijk snel is.
- Beste geval: O(n log n) — wanneer partitionering steeds balans geeft.
- Worst case: O(n²) — bijvoorbeeld als je telkens de kleinste of grootste als pivot kiest op reeds gesorteerde input.
- Ruimtecomplexiteit: gemiddeld O(log n) extra ruimte door recursie (in-place variant gebruikt geen extra array). Slechtste geval O(n) recursiediepte zonder optimalisaties.
- Stabiliteit: Quicksort is van nature niet-stabiel (gelijke elementen kunnen van volgorde veranderen) tenzij speciale maatregelen worden genomen.
Praktische optimalisaties
- Randomized pivot: kies de pivot willekeurig om de kans op het worst case te verkleinen.
- Median-of-three: kies de pivot als de mediaan van bijvoorbeeld het eerste, middelste en laatste element om slechte partities te vermijden.
- Three-way partitioning: efficiente handelwijze bij veel gelijke elementen (verdeelt in <, =, > pivot).
- Gebruik insertion sort op kleine subarrays: voor kleine n is insertion sort vaak sneller; vaak wordt een drempel (bv. n < 10–20) gebruikt.
- Tail-recursion eliminatie / iteratieve implementatie: reduceert recursiediepte en voorkomt stapel-overloop; Quicksort kan gemodeerd worden met een expliciete stack of door altijd de kleinere helft recursief te verwerken en de grotere iteratief.
- Introsort: combineer Quicksort met Heapsort als de recursiediepte te groot wordt, zodat je gegarandeerd O(n log n) worst-case krijgt.
Wanneer Quicksort gebruiken?
Quicksort wordt vaak gebruikt in bibliotheken en toepassingen omdat het in de praktijk doorgaans sneller is dan andere O(n log n) algoritmen door lage constante factoren en goede cachelocaliteit. Als stabiliteit vereist is of je gegarandeerd O(n log n) in het slechtste geval nodig hebt, zijn respectievelijk mergesort of heapsort (of introsort) betere keuzes.
Kort samengevat: Quicksort is een snelle, in-place, niet-stabiele sorteermethode gebaseerd op verdeel-en-heers. Met slimme pivotkeuze en optimalisaties is het in veel praktische situaties de beste keuze.
Algoritme
- Kies een willekeurig element in de matrix, dit wordt nu het draaipunt.
- Verdeel de elementen. Vergelijk alle elementen in de matrix met de spil, de elementen die lager zijn dan de spil worden naar links van de spil verplaatst, en alle elementen in de matrix die hoger zijn dan de spil worden naar rechts van de spil verplaatst. Onze spil staat nu op de gesorteerde positie.
- Terugverwijzen naar de twee partities. Pas de bovenstaande twee stappen toe op de twee partities die we in stap 2 hebben gemaakt.
Vaak wordt het meest linkse element als spil gekozen. De recursie betekent dat het algoritme exact hetzelfde algoritme uitvoert op de twee partities die ontstaan zijn door de vergelijkingen met de spil. Merk op dat dit algoritme de array blijft verdelen in subarrays, en deze subarrays blijft verdelen in nog kleinere subarrays. Telkens wanneer het dit doet, kiest het een nieuwe spil binnen de subarray en vergelijkt het de elementen met de subarray. Het basisgeval is wanneer het algoritme een subarray met slechts één element bereikt, waarin het gewoon stopt omdat één element niet gesorteerd hoeft te worden.
Gerelateerde artikelen
Auteur
AlegsaOnline.com Quicksort: definitie en werking van het snelle verdeel-en-heers sorteeralgoritme Leandro Alegsa
URL: https://nl.alegsaonline.com/art/80540
Bronnen
- web.archive.org : "Sir Antony Hoare | Computer History Museum"
