Array versus gelinkte lijst: toegang, invoegen en verwijderen, geheugenindeling, cache en tijdcomplexiteit
Een array slaat elementen van hetzelfde type zonder tussenruimte naast elkaar in het geheugen op, zodat de positie van elk element uit zijn index kan worden berekend en in constante tijd kan worden gelezen of geschreven. Een gelinkte lijst is een datastructuur waarin elk element een waarde en een pointer naar het volgende element bevat, en de elementen worden verbonden door die pointers te volgen, zodat ze op verschillende plaatsen in het geheugen kunnen staan. Een array leest snel, maar invoegen of verwijderen in het midden betekent dat de elementen erachter moeten opschuiven. Een gelinkte lijst kan invoegen of verwijderen door alleen pointers te veranderen zodra de positie bekend is, maar het i-de element lezen betekent vanaf het begin doorlopen. De vuistregel: gebruik een array als je vooral op index leest, en een gelinkte lijst als je vaak op bekende posities invoegt of verwijdert.
| Kenmerk | Array | Gelinkte lijst |
|---|---|---|
| Geheugenindeling | De elementen staan naast elkaar in één aaneengesloten blok | De elementen liggen verspreid en zijn met pointers verbonden |
| Het i-de element lezen | O(1): het adres is beginadres + i × elementgrootte | O(n): vanaf het begin i keer de pointers volgen |
| Een waarde zoeken | O(n) lineair zoeken als niet gesorteerd; O(log n) met binair zoeken als gesorteerd | O(n), ook als gesorteerd; binair zoeken kan niet, omdat je niet naar het midden kunt springen |
| Invoegen of verwijderen in het midden | O(n): de elementen erachter schuiven één voor één op | O(1) als de positie (het voorgaande element) bekend is; alleen pointers veranderen |
| Achteraan toevoegen | O(1) als er vrije ruimte is; een dynamische array die zijn capaciteit verdubbelt, kopieert af en toe alles, maar is gemiddeld (geamortiseerd) O(1) | O(1) als een pointer naar het laatste element wordt bijgehouden |
| Van grootte veranderen | De grootte van een array met vaste grootte ligt vast bij het aanmaken; vergroten betekent een nieuw blok reserveren en kopiëren | Ruimte wordt per element gereserveerd, dus de lijst groeit alleen zoveel als nodig |
| Geheugengebruik | Alleen de elementen zelf (een dynamische array houdt wat reservecapaciteit aan) | Extra ruimte voor een pointer per element (twee in een dubbel gelinkte lijst) |
| Cachevriendelijkheid | Goed: de elementen zijn aaneengesloten, dus sequentieel lezen benut caches en prefetching goed | Slecht: de elementen liggen vaak verspreid, dus zelfs dezelfde O(n)-doorloop kan veel trager zijn dan bij een array |
| Typische toepassingen | Tabellen die op index worden gelezen en geschreven, matrices en afbeeldingen, data om te sorteren of binair te doorzoeken, implementaties van stacks en wachtrijen | Reeksen met veel invoegingen en verwijderingen, chaining in hashtabellen, beheer van vrije ruimte |
De getalswaarden zijn typische ordegroottes en variëren per procesgeneratie en product.