Fiche de révision

Fonctionnement d'un programme récursif


Les fonctions récursives permettent de simplifier l'écriture de nombreux problèmes. Nous présentons ici leur fonctionnement et une méthodologie d'écriture et d'analyse de ces fonctions.

IIntroduction à la récursivité

Une fonction récursive est une fonction qui s'appelle elle-même. Voici un premier exemple classique.

Tableau de 5 lignes, 2 colonnes ;Corps du tableau de 5 lignes ;Ligne 1 : ; def expo(a, n):; Ligne 2 : ;     if n == 0:; Ligne 3 : ;         return 1; Ligne 4 : ;     else:; Ligne 5 : ;         return a * expo(a, n - 1);

Cette fonction implémente simplement une façon (récursive) de définir la puissance d'un nombre a0 : a0=1 et an=a×an1.

On remarque que la fonction commence par une condition d'arrêt qui traite le cas de base. Pour étudier le fonctionnement interne de cette fonction, on peut réécrire la fonction précédente :

Mot clé

Un cas de base est une valeur de l'argument pour laquelle le problème se résout immédiatement.

Tableau de 7 lignes, 2 colonnes ;Corps du tableau de 7 lignes ;Ligne 1 : ; def expo(a, n):; Ligne 2 : ;     if n == 0:; Ligne 3 : ;         print(

IIPile d'exécution

Lors de l'appel d'une fonction récursive, une structure de pile est utilisée en interne.

Une pile fonctionne comme un empilement d'objets (l'image d'une pile d'assiettes est adaptée) : on peut empiler un objet en haut de la pile et enlever le sommet de la pile (on dit dépiler), mais on ne peut pas accéder à un objet qui n'est pas en haut de la pile.

La pile utilisée, appelée pile d'exécution, est de taille limitée. Au-delà d'un certain nombre d'appels récursifs, 1 000 par défaut en Python, il y a une erreur de dépassement de la taille de la pile (stack overflow). Cette pile contient une trace de tous les appels de fonction qui ne se sont pas encore terminés.

Concrètement, un appel récursif à expo(2, 3) donne, de manière très simplifiée :

Tableau de 4 lignes, 2 colonnes ;Corps du tableau de 4 lignes ;Ligne 1 : ; expo(2, 3) = 2 * expo(2 ,2); Ligne 2 : ;             expo(2, 2) = 2 * expo(2 ,1); Ligne 3 : ;                         expo(2, 1) = 2 * expo(2 ,0); Ligne 4 : ;                                     expo(2, 0) = 1;

Évolution de la pile d'exécution, puis dépilement pour évaluer :

06461_chap02_fiche08_i01

IIIÉcriture d'une fonction récursive

Une fonction récursive simple s'écrit sous la forme :

Tableau de 4 lignes, 2 colonnes ;Corps du tableau de 4 lignes ;Ligne 1 : ; def fun(args):; Ligne 2 : ;     if condition d'arrêt:; Ligne 3 : ;         return valeur; Ligne 4 : ;     appel récursif;

Pour écrire une fonction récursive on :

− détermine le type de données à renvoyer ;

− détermine pour quelle(s) valeur(s) de l'argument le problème est résolu et on écrit la condition d'arrêt ;

− détermine de quelle manière la taille du problème est réduite (argument entier qui décroît strictement, liste dont la taille diminue, etc.) ;

− écrit l'appel récursif en prenant garde à ce que le type de données qu'il renvoie soit cohérent avec celui renvoyé par la condition d'arrêt.

IVÉtude de la complexité d'une fonction récursive

On note Tn le nombre d'opérations nécessaires pour évaluer une fonction récursive sur un problème de taille n. Pour évaluer Tn on cherche une relation de récurrence impliquant Tn, puis on résout la relation de récurrence.

Exemple : nombre d'opérations pour le calcul de la puissance d'un nombre. On a T0=1 et Tn+1=Tn+1. On reconnaît une suite arithmétique, d'où Tn=n+1.

Voici quelques complexités classiques :

Tableau de 4 lignes, 2 colonnes ;Corps du tableau de 4 lignes ;Ligne 1 : Relation de récurrence; Complexité; Ligne 2 : Tn=Tn−1+Θ1; Θn; Ligne 3 : Tn=Tn−1+Θn; Θn2; Ligne 4 : Tn=2Tn−1+Θ1; Θ2n;

Pour lire la suite

Je m'abonne

Et j'accède à l'ensemble
des contenus du site