
Remarque : On utilise la mˆeme syntaxe de d´ef. de fonctions : il n’y pas de d´eclaration particuli`ere
pour les fonctions r´ecursives (important pour les habitu´es `a Caml).
Exemple 2, exercice : (i) Si (un)est d´efinie par r´ec. par
u0=0,
∀n∈N, un+1=√2+un
, d´efinir une
fonction r´ecursive uen Python qui renvoie la valeur u(n)=unpour tout n∈N.
(ii) Exp´erimentation : Que se passe-t-il si on veut calculer u1000 ?
(iii) Calculer u1000 `a l’aide d’un algorithme it´eratif (boucle).
2.2 Comment ¸ca marche une fonction r´ecursive ?
Un sch´ema intuitif
On peut sch´ematiser les op´erations faites pour le calcul de fact(3) comme suit :
1.2 Profondeur de pile
Afin de protéger le système contre la saturation mémoire engendrée par les boucles
infinies, Python est muni d’une protection simple. Le nombre maximal d’appels récursifs
autorisé par une même fonction est limité. Ce paramètre limite s’appelle la
profondeur de
pile, et vaut 1000 dans les installations Python standard.
Console python
1>>> import sys
2>>> sys.getrecursionlimit()
31000
Cela signifie simplement qu’une fonction récursive ne peut pas s’appeler plus de
1000
fois.
C’est un paramètre réglable par la commande
sys.setrecursionlimit()
. Ainsi, l’appel
des fonctions précédentes,
r1()
ou
r2()
, conduit systématiquement au message d’erreur
RuntimeError: maximum recursion depth exceeded.
Exercice 1
Fixer la limite de la pile à 10. Créer une fonction récursive qui affiche un comp-
teur permettant de vérifier que l’erreur se produit au bout du 10eappel.
Réponse 1
_______________________________________________________
_______________________________________________________
_______________________________________________________
_______________________________________________________
_______________________________________________________
1.3 Les 3 règles de la programmation récursive
Pour éviter qu’une fonction récursive ne finisse en boucle infinie, elle doit toujours possé-
der une condition d’arrêt inévitablement déclenchée par un test.
De façon générale, trois propriétés sont à respecter pour s’assurer du bon fonctionnement
d’une fonction récursive :
– elle doit contenir un cas de base ;
– elle doit modifier son état pour pouvoir se ramener au cas de base ;
– elle doit s’appeler elle-même.
Vérifions cette définition dans le cas de la fonction factorielle
n!=!1 si n=0
n×(n−1)! si n≥1
On constate bien ici que le cas de base existe, 0!
=
1, que la fonction modifie son état par la
relation (n−1) et s’appelle elle-même,(n−1)!.
Implémenté sous forme récursive, la factorielle nécessite l’utilisation de la commande
return qui doit renvoyer à l’étage précédent la valeur calculée.
Console python
1>>> def fact(n):
2... if n==0:
3... return 1
4... else:
5... return n*fact(n-1)
Console python
1>>> fact(5)
2120
Le déroulement des opérations nécessaires est présenté ci-après. Il y a diminution pro-
gressive de la valeur à calculer, lors de la « descente », jusqu’à arriver au cas de base, qui
déclenche alors la « remontée » des valeurs du contexte pour donner la valeur finale.
FIGURE 1 – Factorielle récursive
Exercice 2
Implémenter une version itérative de la fonction factorielle.
Réponse 2
_______________________________________________________
_______________________________________________________
_______________________________________________________
_______________________________________________________
_______________________________________________________
2 Différents types de récursivité
Il s’agit surtout de citer les différentes situations de récursivité qui existent. Les définitions
parlent d’elles-mêmes.
2/7
La gestion informatique de ce sch´ema
Lorsqu’on appelle fact(3), dans l’espace m´emoire local de la fonction, on d´efinit n=3, le else
s’ex´ecute et donc voudrait ex´ecuter le return 3*fact(2).
Mais cette ex´ecution est diff´er´ee car pour ex´ecuter ce return, on doit d’abord appeler fact(2).
Se cr´ee alors un nouveau sous-espace m´emoire d´edi´e `a l’appel de cette fonction fact avec une
variable locale n=2 dans laquelle va s’ex´ecute fact.
Pendant toute la phase de descente du sch´ema pr´ec´edent, on cr´ee donc quatre espaces de va-
riables locales qu’on nommera ici espace 3,2,1,0, avec des variables locales correspondantes qu’on
indicera par le num´ero de l’espace correspondant n3=3,...,n0=0.
Dans l’espace 0, on peut calculer fact(0).
Avec cette valeur, on peut enfin ex´ecuter le return 1* fact(0) dans l’espace 1 et ainsi de
suite.
Comment rendre ce d´eroulement explicite `a l’aide d’un script ?
def fact(n):
if n==0 :
return 1
else :
print(’--’*n+’> appel de fact’,n-1)
resultat=n*fact(n-1) # on a s´epar´e le calcul du return pour permettre l’affichage
#de la ligne suivante
print(’--’*n+’> retour de fact’,n-1)
return resultat
Qui donne pour fact(3) :
3