Rcursivit 1 Introduction Une fonction rcursive est une
- Slides: 33
Récursivité 1
Introduction § Une fonction récursive est une fonction qui s'appelle même. § Directement (si la fonction P appelle directement P , on dit que la récursivité est directe). § Indirectement à travers une ou plusieurs fonctions relais (si P appelle une fonction P 1 , qui appelle une fonction P 2 , . . . , qui appelle une fonction Pn et qui enfin appelle P , on dit qu'il s'agit d'une récursivité indirecte). 2
Introduction § Si f est une fonction comprenant un appel à elle même, soit directement ou indirectement, alors f est une fonction récursive. § directement : int f 1( …) { . . . x= f 1(…); } § indirectement : int f 1( …) { . . . x= f 2(…); } int f 2(. . . ) { . . . x=f 1(. . . ); } 3
Introduction § La récursivité est une manière simple et élégante de résoudre certains problèmes algorithmiques. § Elle permet: § d'écrire des programmes beaucoup plus lisibles; § d'écrire d'une manière très rapide (par rapport d’une manière itérative); § d’utiliser le principe diviser-pour-résoudre. 4
Introduction § La récursivité utilise toujours la pile du programme en cours. § Dans une fonction récursive, toutes les variables locales sont stockées dans la pile, et empilées autant de fois qu'il y a d'appels récursifs. § La pile se remplit progressivement, et si on ne fait pas attention on arrive à un "débordement de pile". Ensuite, les variables sont désempilées. § Toute fonction récursive comporte une instruction (ou un bloc d'instructions) nommée "point terminal" ou "point d'appui" ou "point d'arrêt", qui indique le reste des instructions ne doit plus être exécuté. 5
Définition récursive § La fonction récursive est composée de deux partie: une partie strictement récursive et une partie non récursive (base) servant de point de départ à l'utilisation de la définiton récursive. § Structure générale d’une fonction récursive : { } if(/* !condition de convergence */) exit(1); if(/*condition d’arrêt*/) return(/*Ce qu’elle doit retourner*/); else appel récursif Traitement 6
Définition récursive § On peut définir le factoriel d'un nombre n non négatif de deux manières: § définition non récursive: n ! = n * n-1 *. . . 2 * 1 § définition récursive: n ! = n * (n-1) ! et 0 ! = 1 7
Définition récursive § Expression récursive du problème : n ! = n * n-1 *. . . 2 * 1 = n*(n-1)! § Condition d’arrêt : n = 1 ou n = 0 § Convergence (vers la condition d’arrêt): § Si n=1 ou n=0, alors on a convergé! § Si n>1, alors la soustraction à l’étape suivante nous approche de n=1. Donc si n est une entier non négatif ça converge! 8
Fonctions récursives § La grande question qui se pose dans une fonction récursive est celle de l'arrêt de la récursivité (de sortie). § La condition de sortie pour la fonction n! est 0!=1. § Le choix de la condition - vous devrez être sûr qu'elle soit validée à un moment ou à un autre sinon c'est comme si vous créez une boucle infinie sans condition de sortie ! § La syntaxe la plus générale d'une fonction récursive est : <type_de_retour> <nom. Fct>(< args >){ [déclaration de variables] [test d'arrêt] [suite d'instructions] [appel de <nom. Fct>(< args‘ >)] [suite d'instructions] return <résultat>; } 9
Fonctions récursives § Premier exemple - calcul de n!. (0!=1!=1 et n! = n * (n-1)!). § De manière itérative, on écrit : unsigned long factorielle(int n){ unsigned long f = 1; for(int k = n; k > 1; k--) f *= k; return f; } le calcul par accumulation du produit dans la variable f 10
Fonctions récursives § Premier exemple - calcul de n!. (0!=1!=1 et n! = n * (n-1)!). § De manière récursive, on peut écrire : Hypothèse de convergence: n>=0 unsigned long fact(int n){ if (n < 0) exit (EXIT_FAILURE); else if(n == 1 || n == 0) return 1 L; else return n * fact(n-1); } Cas de base (Condition d’arrêt) La relation de récurrence (appel récursif) 11
Fonctions récursives Une fonction de ce type possède deux parcours: Empilement des appels récursifs (la phase de 1. descente) (par exemple pour fact(3)) § Variable - paramètre L’adresse de la fonction + variable de retour 12
Fonctions récursives § Dépilement des appels récursifs (la phase de remontée) pour (fact(3)) 13
Fonctions récursives § La phase de descente et de remontée dans la pile des appels de la fonction récursive: Au moment de la remontée, où la condition de sortie est vraie les appels enregistrés sont dépilés. 14
Fonctions récursives § La récursivité ne marche que si on ne fait pas déborder la pile d'appels. unsigned long fact(int n){ if (n < 0) exit (EXIT_FAILURE); else if(n == 1 || n == 0) return 1 L; else return n * fact(n+1); } La fonction ne termine pas § Le problème fondamental de l'informatique de pouvoir prouver qu'une fonction (ou un algorithme) termine. 15
Fonctions récursives Variables locales, arguments de fonctions § Lorsqu'une fonction récursive définit des variables locales, un exemplaire de chacune d'entre elles est crée à chaque appel récursif de la fonction. § Il en est de même des arguments des fonctions. 16
Fonctions récursives Variables locales, arguments de fonctions § Exemple - considérons une fonction void miroir() qui lit caractère par caractère une chaîne terminée par '? ' et l'affiche dans l'ordre inverse de celui de la lecture. § Version non récursive #include <stdio. h> void miroir() { char s[20], c; int i=0; while( (c=getchar())!='? ') s[i++]=c; s[i]='