Achtergrond
Recursie als mechanisme wordt vaak toegepast voor elegante oplossingen van boomdoorloopproblemen, het berekenen van faculteiten, en snelle sortering. In C worden recursieve aanroepen direct geïmplementeerd, omdat een functie zichzelf kan aanroepen via een gewone naamvermelding.
Probleem
Recursie is handig, maar brengt risico's met zich mee voor snelle stapeloverloop door diepe insluiting (stack overflow). Bovendien werkt het inefficiënt voor grote invoergegevens zonder optimalisaties (bijvoorbeeld, door gebrek aan staartrecursie).
Oplossing
Controleer voor het toepassen van recursie de maximaal mogelijke diepte, implementeer basisvoorwaarden (base case), overweeg het geheugenverbruik (stapel), en herschrijf in kritische gevallen het algoritme naar een iteratieve variant.
Voorbeeldcode:
// Zoek faculteit recursief unsigned long factorial(unsigned int n) { if (n <= 1) return 1; // basisgeval return n * factorial(n - 1); // recursief geval }
Belangrijkste kenmerken:
Kan een functie in C zichzelf rechtstreeks aanroepen met een willekeurige naam?
Nee. Een functie roept alleen zichzelf aan met behulp van zijn eigen naam, die gedefinieerd moet zijn op het moment van aanroep (of minstens vooraf moet worden gedeclareerd).
Is recursie altijd efficiënter dan een lus?
Nee! Iteratieve oplossingen werken vaak sneller en betrouwbaarder, omdat ze de stapel niet snel belasten en geen extra kosten met zich meebrengen voor functieaanroepen.
Wordt de stapel na recursie weer naar de oorspronkelijke staat teruggebracht?
Ja, de stapel wordt volledig vrijgegeven na het verlaten van elke recursieve functie. Na het voltooien van de buitenste functie wordt het geheugen weer in de oorspronkelijke staat teruggebracht.
Een ontwikkelaar realiseerde een functie voor boomdoorloop met recursie voor 100.000 knooppunten zonder dieptecontrole. Dit leidde tot stack overflow.
Voordelen:
Het algoritme werd geïmplementeerd met bijhouden van de recursiediepte en bescherming tegen te diepe insluiting, grote doorlopen worden in batches verdeeld (iteratieve variant).
Voordelen: