Aller au contenu principal

Informatique · Terminale · 5 min de lecture

Récursivité : une fonction qui s'appelle elle-même

Une fonction récursive s'appelle elle-même sur une donnée plus petite ; elle comporte au moins un cas de base, traité sans appel récursif, qui garantit l'arrêt ; analyser un appel par la pile des appels ou l'arbre des appels ; compter les appels effectués ; écrire une version récursive d'un calcul (factorielle, puissance, somme des chiffres).

Chapitre du programme : Numérique et sciences informatiques (spécialité)

Bloc 1 sur 7 · Comprendre

Comprendre : un problème plus petit du même type

Une fonction est récursive lorsqu’elle s’appelle directement ou indirectement. Dans les exemples de cette leçon, les appels portent sur une donnée naturelle plus petite ; c’est ce qui permettra de justifier l’arrêt. Elle repose sur deux éléments :

  1. un cas de base, traité directement, sans appel récursif ;
  2. un cas récursif, qui ramène le problème à un problème plus petit du même type.

Dans les fonctions numériques de cette leçon, n est un entier naturel. La factorielle de n, notée n !, est le produit 1 × 2 × … × n, avec 0! = 1. Elle vérifie n ! = n × (n − 1)! : c'est un cas récursif tout trouvé.

def factorielle(n):
    if n == 0:
        return 1
    return n * factorielle(n - 1)

print(factorielle(5))
120

L'appel factorielle(5) déclenche factorielle(4), qui déclenche factorielle(3)… jusqu'au cas de base factorielle(0), qui renvoie 1 sans rien rappeler. Les résultats remontent ensuite : 1, puis 1 × 1, 2 × 1, 3 × 2, 4 × 6, 5 × 24 = 120.

Bloc 2 sur 7 · Approfondir

Approfondir : la pile des appels

Chaque appel en attente garde ses propres variables : le système les empile dans la pile des appels. Le dernier appel lancé est le premier terminé. Ce programme le rend visible :

def compte(n):
    if n == 0:
        print("décollage")
    else:
        print(n)
        compte(n - 1)
        print("retour de", n)

compte(3)
3
2
1
décollage
retour de 1
retour de 2
retour de 3

Les messages « retour de » s'affichent dans l'ordre inverse des appels : compte(1) termine en premier, compte(3) en dernier.

Terminaison. La terminaison mathématique des exemples se justifie par une donnée entière naturelle qui diminue strictement jusqu’au cas de base. En pratique, une récursion même terminante peut dépasser la limite de profondeur de Python avant de l’atteindre. Sans cas de base, ou avec une donnée qui ne diminue pas, les appels s'empilent sans fin et Python interrompt le programme avec une erreur RecursionError.

Un coût parfois caché. Une fonction qui s'appelle DEUX fois peut recalculer très souvent les mêmes valeurs :

appels = []

def fibo(n):
    appels.append(n)
    if n < 2:
        return n
    return fibo(n - 1) + fibo(n - 2)

print(fibo(10), len(appels))
55 177

Pour obtenir fibo(10) = 55, la fonction est appelée 177 fois : fibo(2), par exemple, est recalculé de nombreuses fois. La programmation dynamique, au programme de terminale, évite ces recalculs en mémorisant les résultats.

Bloc 3 sur 7 · Exemple

Exemple guidé : somme des chiffres

Énoncé. Que renvoie somme_chiffres(4705) ?

def somme_chiffres(n):
    if n < 10:
        return n
    return n % 10 + somme_chiffres(n // 10)

print(somme_chiffres(4705))

Déroulé. n % 10 est le chiffre des unités, n // 10 le nombre privé de ce chiffre.

Tableau : Appel, Cas, Valeur renvoyée
AppelCasValeur renvoyée
somme_chiffres(4705)récursif5 + somme_chiffres(470)
somme_chiffres(470)récursif0 + somme_chiffres(47)
somme_chiffres(47)récursif7 + somme_chiffres(4)
somme_chiffres(4)base (4 < 10)4

En remontant : 4, puis 7 + 4 = 11, puis 0 + 11 = 11, puis 5 + 11 = 16.

16

Bloc 4 sur 7 · Visualiser

Voir : descendre, puis remonter

Tableau : Phase, factorielle(3)
Phasefactorielle(3)
descentefactorielle(3) attend factorielle(2)
descentefactorielle(2) attend factorielle(1)
descentefactorielle(1) attend factorielle(0)
cas de basefactorielle(0) renvoie 1
remontéefactorielle(1) renvoie 1 × 1 = 1
remontéefactorielle(2) renvoie 2 × 1 = 2
remontéefactorielle(3) renvoie 3 × 2 = 6

Continuez sur votre lancée

Vous avez découvert l’essentiel et un exemple. Retrouvez la suite du cours et les points à retenir, puis passez à l’entraînement guidé dans votre compte.

  • Les formules et les repères à retenir
  • Les erreurs fréquentes expliquées
  • Un exercice avec des aides et sa correction

L’accès gratuit comprend les cours et exercices de votre niveau choisi.

Sources

  • BO spécial n°8 du 25 juillet 2019 — programme de spécialité numérique et sciences informatiques de terminale, rubrique « Langages et programmation »
  • T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein, Algorithmique (Introduction to Algorithms), 3e édition française, Dunod
  • Documentation officielle de Python 3 — The Python Tutorial, § 4.8 « Defining Functions » (https://docs.python.org/3/tutorial/controlflow.html)

Vous pensez avoir trouvé une erreur dans cette leçon ? Signalez-la par e-mail.

Explorer les autres cours

Accès rapide