Fiche Récursivité
Fiche de Révision : La Récursivité en C
1. Introduction à la Récursivité
La récursivité est une technique de programmation où une fonction s’appelle elle-même pour résoudre un problème. Elle repose sur des relations de récurrence et agit comme une boucle implicite.
Pourquoi utiliser la récursivité ?
- Permet de résoudre des problèmes naturellement récursifs (ex. : suites, arbres).
 - Offre une écriture plus intuitive et élégante.
 - Peut être plus efficace pour certains algorithmes (ex. : parcours d’arbres).
 - Remplace parfois les boucles pour des tâches répétitives.
 - Tout algorithme récursif peut être transformé en version itérative.
 
2. Composantes d’une Fonction Récursive
Une fonction récursive comporte toujours :
- Une condition d’arrêt (cas de base) pour éviter une boucle infinie.
 - Un appel récursif qui ramène le problème à une version plus simple.
 
Forme générale :
1
2
f(x) = si c(x) alors g(x) // condition d'arrêt
       sinon h(f(s(x)), x) // appel récursif
Avec :
c(x): condition d’arrêt.g(x): cas trivial retournant une valeur constante.s(x): fonction successeur de x.h(f(s(x)),x): appel récursif.
Types de récursivité :
- Simple : Un seul appel récursif dans la fonction.
 - Multiple : Plusieurs appels récursifs (ex. : Fibonacci).
 - Terminale : L’appel récursif est la dernière instruction (optimisable).
 - Non Terminale : L’appel récursif est suivi d’une opération.
 - Croisée : Deux fonctions s’appellent mutuellement.
 
3. Exemples de Fonctions Récursives
3.1 Factorielle d’un Nombre (Récursivité Non Terminale)
La factorielle suit la relation : $N! = N × (N-1)!$ avec $1! = 1$.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
int factorielle(int n) {
    if (n == 1) {
        return 1; // Cas de base
    }
    return n * factorielle(n - 1); // Récursivité
}
int main() {
    int nombre = 5;
    printf("Factorielle de %d = %d\n", nombre, factorielle(nombre));
    return 0;
}
3.2 Factorielle en Récursivité Terminale
La version terminale évite de stocker des appels récursifs dans la pile.
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int factorielleRT(int n, int acc) {
    if (n == 0) return acc;
    return factorielleRT(n - 1, acc * n);
}
int main() {
    int nombre = 5;
    printf("Factorielle de %d = %d\n", nombre, factorielleRT(nombre, 1));
    return 0;
}
3.3 Suite de Fibonacci (Récursivité Multiple)
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int fibonacci(int n) {
    if (n < 2) return n;
    return fibonacci(n - 1) + fibonacci(n - 2); // Appels multiples
}
int main() {
    int nombre = 6;
    printf("Fibonacci(%d) = %d\n", nombre, fibonacci(nombre));
    return 0;
}
4. Arbres de Récursivité
Un arbre de récursivité permet de visualiser l’enchaînement des appels récursifs d’une fonction.
Exemple : factorielle(5)
1
2
3
4
5
6
factorielle(5)
└── 5 * factorielle(4)
    └── 4 * factorielle(3)
        └── 3 * factorielle(2)
            └── 2 * factorielle(1)
                └── 1 (cas de base)
Chaque nœud représente un appel de la fonction. Lorsque le cas de base est atteint, les résultats sont remontés pour produire la réponse finale.
5. Erreurs courantes
- Oublier le cas de base → Boucle infinie entraînant un dépassement de pile.
 - Récursivité non optimisée → Complexité exponentielle dans certains cas.
 - Stack Overflow → Trop d’appels récursifs profonds sans optimisation.
 - Utiliser une récursivité inefficace → Peut ralentir le programme (ex. : Fibonacci naïf).
 
6. Bonnes Pratiques
- Toujours définir un cas de base clair.
 - Utiliser la récursivité terminale quand c’est possible.
 - Optimiser avec la mémorisation (memoization) pour éviter les recalculs inutiles.
 - Vérifier la profondeur de récursion pour éviter les erreurs de dépassement de pile.
 - Évaluer si une solution itérative est plus efficace.
 
 Le contenu de cet article est la propriété exclusive de son auteur.