🔄 Notions de base : La Récursivité

Comprendre le principe d’auto-appel, la condition d’arrêt et la pile d’exécution.

📌 Définition

La récursivité est une méthode algorithmique qui consiste à appeler un sous-programme dans son propre corps. Un sous-programme récursif fait appel à lui-même jusqu’à ce qu’une condition d’arrêt soit vérifiée. À chaque appel, une nouvelle instance du module est empilée avec ses propres paramètres formels et variables locales.

1. Condition(s) d’arrêt :
Condition fondamentale permettant de stopper les appels récursifs et d’éviter une boucle infinie (dépassement de pile / Stack Overflow).
2. Appel(s) récursif(s) :
L’instruction où le module s’appelle lui-même en réduisant la taille du problème (ex: N-1, sous-chaîne, etc.).
📝 Remarque : itératif ou récursif ?

Sur le plan théorique, toute solution itérative peut être transformée en solution récursive, et réciproquement, toute fonction récursive dite « terminale » (c’est-à-dire dont l’appel récursif est la toute dernière instruction, sans aucun calcul après le retour de l’appel) peut être réécrite sous forme d’une boucle itérative équivalente, en général plus économe en mémoire (pas d’empilement d’appels).

En pratique, ce n’est pas toujours simple ni souhaitable :

  • Récursif ➔ Itératif : direct pour la récursivité terminale (ex : Mystere1, Mystere4 ci-dessous, la factorielle, la puissance…). Pour une récursivité non terminale (un calcul a lieu après l’appel récursif, comme Retourner A + Mystere1(A, B-1)), la traduction itérative demande souvent de gérer soi-même une pile explicite pour reproduire le comportement de la pile d’exécution.
  • Itératif ➔ Récursif : toujours possible en transformant les variables de boucle en paramètres de la fonction et la condition de boucle en condition d’arrêt.

Certains problèmes, en revanche, n’ont pas de solution itérative simple et sont naturellement (voire quasi exclusivement) traités par récursivité, en particulier lorsque la structure de données elle-même est récursive (arbres, listes chaînées) ou lorsque l’algorithme doit explorer plusieurs branches à chaque étape :

  • Les Tours de Hanoï (voir la simulation plus bas) : la formulation itérative existe mais est nettement moins naturelle et nécessite de gérer explicitement une pile de mouvements ; la version récursive découle directement de la définition du problème.
  • Le parcours d’arbres et de structures récursives (arbres binaires, dossiers/sous-dossiers, expressions imbriquées) : chaque nœud pointe vers d’autres sous-arbres de même nature, ce que la récursivité modélise directement.
  • Le backtracking (résolution de labyrinthes, du sudoku, des N-reines, génération de toutes les combinaisons/permutations) : il faut explorer puis « revenir en arrière », ce que la pile d’appels gère naturellement.
  • La fonction d’Ackermann (exercice 29 ci-dessous) : sa croissance et sa définition mathématique n’admettent pas d’équivalent itératif simple sans pile explicite très complexe.
  • Le tri fusion et le tri rapide : le principe « diviser pour régner » (diviser le tableau, trier chaque moitié, fusionner) est intrinsèquement récursif.

📐 Exemple 1 : Calcul de la Factorielle (N!)

-- Code de la solution --

🔤 Exemple 2 : Chaîne Palindrome (Python)

def palindrome(ch):
    if ch == "":
        return True
    elif ch[0] != ch[len(ch)-1]:
        return False
    else:
        return palindrome(ch[1 : len(ch)-1])

🎬 Simulation Pile d’Exécution : Fact(N)

Pile d’exécution vide

💻 Exercices Interactifs : Exécution à la main & Simulations

Analysez les fonctions récursives suivantes (qui ne possèdent pas de variables locales). Donnez le résultat d’une exécution à la main, déduisez le rôle de chaque fonction, puis lancez la simulation pour visualiser la pile d’exécution.

▶ Exercice 1 : Fonction Mystere1

Fonction Mystere1(A, B : Entier) : Entier
Début
    Si B = 0 Alors
        Retourner 0
    Sinon
        Retourner A + Mystere1(A, B - 1)
    Fin Si
Fin

🎬 Simulation

1. Exécution à la main :
Quel est le résultat de l’appel Mystere1(4, 3) ?
2. Rôle de la fonction :
Que calcule cette fonction ?

▶ Exercice 2 : Fonction Mystere2

Fonction Mystere2(N : Entier) : Entier
Début
    Si N = 0 Alors
        Retourner 0
    Sinon
        Retourner (N Mod 10) + Mystere2(N Div 10)
    Fin Si
Fin

🎬 Simulation

1. Exécution à la main :
Quel est le résultat de l’appel Mystere2(405) ?
2. Rôle de la fonction :
Que calcule cette fonction ?

▶ Exercice 3 : Fonction Mystere3

Fonction Mystere3(A, B : Entier) : Entier
Début
    Si B = 0 Alors
        Retourner 1
    Sinon
        Retourner A * Mystere3(A, B - 1)
    Fin Si
Fin

🎬 Simulation

1. Exécution à la main :
Quel est le résultat de l’appel Mystere3(2, 3) ?
2. Rôle de la fonction :
Que calcule cette fonction ?

▶ Exercice 4 : Fonction Mystere4

Fonction Mystere4(A, B : Entier) : Entier
Début
    Si B = 0 Alors
        Retourner A
    Sinon
        Retourner Mystere4(B, A Mod B)
    Fin Si
Fin

🎬 Simulation

1. Exécution à la main :
Quel est le résultat de l’appel Mystere4(14, 6) ?
2. Rôle de la fonction :
Que calcule cette fonction ?

▶ Exercice 5 : Fonction Mystere5

Fonction Mystere5(A, B : Entier) : Entier
Début
    Si A < B Alors
        Retourner 0
    Sinon
        Retourner 1 + Mystere5(A - B, B)
    Fin Si
Fin

🎬 Simulation

1. Exécution à la main :
Quel est le résultat de l'appel Mystere5(13, 4) ?
2. Rôle de la fonction :
Que calcule cette fonction ?

🎯 Plus d'entraînement : 30 Exercices de Récursivité

Entraînez-vous à écrire des sous-programmes récursifs avec cette liste complète couvrant les entiers, chaînes et tableaux.

1. Somme de 1 à N

Écrire une fonction récursive qui calcule 1 + 2 + ... + N.

Indice 💡Si N=0 Ret 0 Sinon Ret N + Somme(N-1)

2. Produit A * B

Calculer A * B avec des additions (Exo 1 du cours).

Indice 💡Si B=0 Ret 0 Sinon Ret A + Prod(A, B-1)

3. Puissance A^B

Calculer A exposant B récursivement (Exo 3 du cours).

Indice 💡Si B=0 Ret 1 Sinon Ret A * Puis(A, B-1)

4. Division entière A / B

Calculer A Div B par soustractions (Exo 5 du cours).

Indice 💡Si A

5. Reste A Mod B

Calculer le reste de la division entière par soustractions.

Indice 💡Si A

6. PGCD (Soustractions)

Calculer le PGCD de A et B en soustrayant le plus petit du plus grand.

Indice 💡Si A=B Ret A Si A>B Ret PGCD(A-B,B) Sinon Ret PGCD(A,B-A)

7. PGCD (Euclide)

PGCD utilisant le modulo (Exo 4 du cours).

Indice 💡Si B=0 Ret A Sinon Ret PGCD(B, A Mod B)

8. Suite de Fibonacci

Calculer le N-ième terme : F(N) = F(N-1) + F(N-2).

Indice 💡Si N<=1 Ret N Sinon Ret Fibo(N-1) + Fibo(N-2)

9. Somme des chiffres

Calculer la somme des chiffres d'un entier N (Exo 2 du cours).

Indice 💡Si N=0 Ret 0 Sinon Ret (N Mod 10) + SommeC(N Div 10)

10. Nombre de chiffres

Compter le nombre de chiffres composant un entier N.

Indice 💡Si N<10 Ret 1 Sinon Ret 1 + Compter(N Div 10)

🗼 Jeu : Les Tours de Hanoï

Déplacez toute la pile de disques de la tour A vers la tour C, un disque à la fois, sans jamais poser un disque sur un disque plus petit. Cliquez sur une tour pour prendre son disque du dessus, puis cliquez sur la tour de destination.

Coups joués : 0 — Minimum possible (2ⁿ−1) : 15
💡 Le lien avec la récursivité :

Résoudre Hanoï(N, Source, Auxiliaire, Destination) revient à : déplacer récursivement les N−1 disques du dessus vers l'auxiliaire, déplacer le plus grand disque vers la destination, puis déplacer récursivement les N−1 disques de l'auxiliaire vers la destination.

Procédure Hanoi(N, Source, Auxiliaire, Destination)
Début
    Si N > 0 Alors
        Hanoi(N - 1, Source, Destination, Auxiliaire)
        Afficher "Déplacer disque", N, "de", Source, "vers", Destination
        Hanoi(N - 1, Auxiliaire, Source, Destination)
    Fin Si
Fin