Histoire de la question
La récursivité en tant que mécanisme est souvent utilisée pour des solutions élégantes aux problèmes de parcours d'arbre, de calcul de factorielles, de tri rapide. En C, les appels récursifs sont réalisés directement, car une fonction peut s'appeler elle-même par un simple appel par nom.
Problème
La récursivité est pratique, mais elle comporte des risques de débordement de pile rapide en raison de l'imbrication profonde (dépassement de pile). De plus, elle fonctionne de manière inefficace pour de grandes entrées sans optimisations (par exemple, à cause de l'absence de récursivité terminale).
Solution
Avant d'utiliser la récursivité, il est nécessaire de vérifier la profondeur maximale possible, de mettre en œuvre des conditions limites (cas de base), d'examiner l'utilisation de la mémoire (de la pile), et dans les cas critiques — de réécrire l'algorithme sous une forme itérative.
Exemple de code :
// Recherche de la factorielle de manière récursive unsigned long factorial(unsigned int n) { if (n <= 1) return 1; // cas de base return n * factorial(n - 1); // cas récursif }
Caractéristiques clés :
Une fonction en C peut-elle s'appeler directement avec n'importe quel nom ?
Non. Une fonction s'appelle uniquement par son propre nom, qui doit être défini au moment de l'appel (ou au moins préalablement déclaré).
La récursivité est-elle toujours plus efficace que la boucle ?
Non ! Les solutions itératives fonctionnent souvent plus rapidement et de manière plus fiable, car elles n'épuisent pas rapidement la pile et ne nécessitent pas de coûts supplémentaires liés aux appels de fonctions.
Le tas revient-il à son état initial après la récursion ?
Oui, la pile est complètement libérée au fur et à mesure du retour de chaque fonction récursive. Après la fin de la fonction la plus externe, la mémoire revient à son état précédent.
Un développeur a mis en œuvre une fonction de parcours d'arbre récursivement pour 100 000 nœuds sans vérifier la profondeur. Un débordement de pile est survenu.
Avantages :
L'algorithme a été mis en œuvre en surveillant la profondeur de la récursivité et en protégeant contre une imbrication trop profonde, les grands parcours étant divisés en lots (option itérative).
Avantages :