name: inverse layout: true class: center, middle, inverse --- # Inès de Courchelle ## La récursivité ## 2024-2025  --- layout: false # Plan ## Today 1. Définition 2. Fonction/Procédure récursive 3. Exemples
--- # Définition ## Principes
## En gros .otro-blockquote[La récursivité c’est quand une fonction s’appelle elle-même jusqu’à atteindre une condition d’arrêt] --- # La récursivité ## Définition Algorithme permettant de résoudre un problème en calculant des solutions d'instances plus petites du même problème ## Principes - Une fonction qui s'appelle elle même jusqu'à atteindre une condition d'arrêt - Le résultat de chaque fonction enfant est retourné dans les fonctions parents, jusqu’à retourner à la fonction originale ## Pourquoi ? - Pour gagner en temps d'execution - Pour gagner en mémoire --- # La récursivité ## Illustration #### Le compte à rebours On souhaite créer un Compte à rebours à partir de 10. #### Etape 1 on affiche : 10 #### Etape 2 on affiche : 9 #### Etape 3 on affiche : 8 #### Etape ... on afiche : 0 --- # Le Compte à rebours ## Avant ```c PROCEDURE compteARebours(cpt : entier) DEBUT FAIRE ECRIRE(cpt) cpt <- cpt - 1 TANT QUE(cpt>0) FIN ``` .underR[Il faut transformer ça en récursif] #### Mais comment ? --- # La récursivité ## Étapes 1. La condition d'arrêt 2. La résolution du problème 3. L'appel récursif ## Illustration Afin d'illustrer la récursivité nous allons prendre l'exemple du compte à rebours.
--- # La récursivité ## Le compte à rebours #### 1. La condition d'arrêt Lorsque le compteur arrive à zéro #### 2. La résolution du problème compteur = compteur -1 #### 3. L'appel récursif retourner le compteur
--- # La recursivité ## AVANT ```c PROCEDURE compteARebours(cpt : entier) DEBUT FAIRE ECRIRE(cpt) cpt <- cpt - 1 TANT QUE(cpt>0) FIN ``` ## APRES ```c PROCEDURE compteARebours (cpt : entier) DEBUT SI cpt=0 FAIRE ECRIRE(CPT) SINON ECRIRE(cpt) compteARebours(cpt-1) FIN FIN ``` --- # La recursivité ## L'algo ```c PROCEDURE compteARebours (cpt : entier) DEBUT SI cpt=0 FAIRE ECRIRE(CPT) SINON ECRIRE(cpt) compteARebours(cpt-1) FIN FIN ``` ## Le code ```c void compteARebours (int cpt) { if (cpt==0) printf("%d \n",cpt); else { printf("%d \n",cpt); compteARebours(cpt-1); } } ``` --- # La récursivité ## On peut aussi ... - Faire une procédure récursive - Faire une fonction récursive ## Algo .pull-left[ ```c PROCEDURE compteARebours (cpt : entier) DEBUT SI cpt=0 FAIRE ECRIRE(CPT) SINON ECRIRE(cpt) compteARebours(cpt-1) FIN FIN ``` ] .pull-right[ ```c FONCTION compteARebours (cpt : entier): entier SI (cpt=0) FAIRE retourner 0 SINON printf("%d \n",cpt) retourner compteARebours(cpt-1) FIN FIN ``` ] --- # La recursivité ## L'algo ```c FONCTION compteARebours (cpt : entier): entier SI (cpt=0) FAIRE retourner 0 SINON printf("%d \n",cpt) retourner compteARebours(cpt-1) FIN FIN ``` ## Le code ```c int compteARebours (int cpt) { if (cpt==0) return 0; else { printf("%d \n",cpt); return compteARebours(cpt-1); } } ``` --- # La récursivité ## La var
Cette vidéo ne peut être affichée sur votre navigateur Internet.
Une version est disponible en téléchargement sous
adresse du lien
.
--- # La récursivité ## En gros Un appel récursive remplace une boucle ## Illustration .pull-left[ ```c PROCEDURE helloThere DEBUT POUR i allant de 0 à 4 FAIRE ecrire("coucou') FIN POUR FIN ``` ] .pull-right[ ```c PROCEDURE helloThere(i: entier) DEBUT SI (i=0) ALORS ecrire ("coucou") SINON ecrire ("coucou") i <- i - 1 helloThere(i) FIN SI FIN ``` ] --- # La récursivité ## Terminale .otro-blockquote[Une fonction avec une récursivité terminale est une fonction où l'appel récursif est la dernière instruction à être évaluée. ] ## Non terminale C'est l'inverse ! --- # La récursivité ## Terminale ``` FONCTION exempleT(n : entier) : entier DEBUT SI condition d'arret FAIRE RETOURNER ... SINON RETOURNER exempleT(n-1) FIN ``` ## Non terminale ``` FONCTION exempleT(n : entier) : entier DEBUT SI condition d'arret FAIRE RETOURNER ... SINON RETOURNER n+ exempleT(n-1) FIN ``` --- # Autrement dit ## Composantes d’une fonction récursive ```c f(x) = SI c(x) alors g(x) SINON h(f(s(x)), x) ``` - c(x) est dite condition d’arrêt ; - g(x) est le cas trivial, il peut retourner une valeur constante ; - s(x) est la fonction “successeur” de x ; - h(f(s(x)),x) est l’appel récursif, fonction de x et du successeur de x. Si h est la fonction identité, la récursivité est dite terminale; non terminale sinon. --- # Autrement dit ## Terminale - Tout appel récursif de f est de la forme return f(...) - La valeur retournée est directement la valeur obtenue par un appel récursif, sans qu'il n'y ait aucune opération sur cette valeur -Une fonction avec une récursivité terminale est une fonction où l'appel récursif est la dernière instruction à être évaluée. ## Non terminale C'est l'inverse ! --- # La récursivité ## Somme d'un tableau On considère le tableau suivant :
## Comment faire ? 1. Récursif non terminal 2. Récursif terminal --- # La récursivité ## NON TER : Somme d'un tableau
#### 1. La condition d'arrêt Je suis à la fin de mon tableau #### 2. La résolution du problème somme = tab[i] + somme #### 3. L'appel récursif sommeTableau avec la case suivante i = i+1 --- # La récursivité ## NON TER : Somme d'un tableau
#### 1. La condition d'arrêt
--- # La récursivité ## NON TER : Somme d'un tableau
#### 2. La résolution du problème
--- # La récursivité ## NON TER : Somme d'un tableau
#### 3. L'appel récursif
--- # La récursivité ## NON TER : Somme d'un tableau #### ALGO ```c FONCTION somme(i : entier, tab: tableau d'entiers) : entier DEBUT SI (i=TAILLE) ALORS retourner 0 SINON RETOURNER TAB[i] + somme(i+1,tab) FIN SI FIN ``` --- # La récursivité ## NON TER : Somme d'un tableau #### En C ```c int somme(int i, int tab[TAILLE]){ if(i==TAILLE){ return 0; } else{ return tab[i] + somme(i+1,tab); } } ``` --- # La récursivité ## EN NON TERMINAL : Somme d'un tableau
Cette vidéo ne peut être affichée sur votre navigateur Internet.
Une version est disponible en téléchargement sous
adresse du lien
.
--- # La récursivité ## NON TER : Somme d'un tableau #### EXPLICATION
--- # La récursivité ## NON TER : Somme d'un tableau #### EXPLICATION
--- # La récursivité ## EN TERMINAL : Somme d'un tableau
--- # La récursivité ## EN TERMINAL : Somme d'un tableau
--- # La récursivité ## EN TERMINAL : Somme d'un tableau ```c FONCTION somme(i : entier, tab: tableau d'entiers, acc :entier) : entier DEBUT SI (i=TAILLE) ALORS retourner acc SINON RETOURNER somme(i+1,tab,acc+tab[i]) FIN SI FIN ``` --- # La récursivité ## EN TERMINAL : Somme d'un tableau
--- # La récursivité ## EN TERMINAL : Somme d'un tableau
--- # La récursivité ## EN TERMINAL : Somme d'un tableau
Cette vidéo ne peut être affichée sur votre navigateur Internet.
Une version est disponible en téléchargement sous
adresse du lien
.
--- # La récursivité ## Des exemples Mathèmatiques - Factorielle - Fibonacci
--- # La récursivité ## Exemple : la factorielle ``` 0! = 1 1! = 1 2! = 1 × 2 = 2 3! = 1 × 2 × 3 = 6 4! = 1 × 2 × 3 × 4 = 24 ``` ## Identifier #### 1. La condition d'arrêt #### 2. La résolution du problème #### 3. L'appel récursif --- # La récursivité ## La factorielle #### En math n!=n*(n-1)! #### En gros ! 4! = 4 x 3! = 4 x (3 x 2!) = 4 x (3 x (2 x 1!)) = 4 x (3 x (2 x (1 x 0!)))
--- # La récursivité
--- # La récursivité
--- # La récursivité
--- # La récursivité ## La factorielle ``` FONCTION factorielle(n : entier) : entier DEBUT SI n=0 ALORS RETOURNER 1 SINON RETOURNER n * factorielle(n-1) FIN ``` --- # La récursivité ## La factorielle ``` FONCTION factorielle(n : entier) : entier DEBUT SI n=0 ALORS RETOURNER 1 SINON RETOURNER n * factorielle(n-1) FIN ```
--- # La récursivité ## La factorielle ``` FONCTION factorielle(n : entier) : entier DEBUT SI n=0 ALORS RETOURNER 1 SINON RETOURNER n * factorielle(n-1) FIN ```
--- # La récursivité ## La factorielle ``` FONCTION factorielle(n : entier) : entier DEBUT SI n=0 ALORS RETOURNER 1 SINON RETOURNER n * factorielle(n-1) FIN ```
--- # La récursivité ## La factorielle ``` FONCTION factorielle(n : entier) : entier DEBUT SI n=0 ALORS RETOURNER 1 SINON RETOURNER n * factorielle(n-1) FIN ```
--- # La récursivité ## La factorielle ``` FONCTION factorielle(n : entier) : entier DEBUT SI n=0 ALORS RETOURNER 1 SINON RETOURNER n * factorielle(n-1) FIN ```
--- # La récursivité ## La factorielle ``` FONCTION factorielle(n : entier) : entier DEBUT SI n=0 ALORS RETOURNER 1 SINON RETOURNER n * factorielle(n-1) FIN ```
--- # La récursivité ## La factorielle en terminal Est ce possible ? ## Comment ? - Avec un accumulateur - Stocker les résultats intermédiaires --- # La récursivité ## La factorielle en terminal ``` FONCTION factorielleTerminale(n : entier, acc : entier) : entier DEBUT SI n=0 ALORS RETOURNER acc SINON RETOURNER factorielleTerminale(n-1,acc*n) FIN ``` ## La factorielle en non terminal ``` FONCTION factorielle(n : entier) : entier DEBUT SI n=0 ALORS RETOURNER 1 SINON RETOURNER n * factorielle(n-1) FIN ``` --- # La récursivité ## La factorielle en terminal ``` FONCTION factorielleTerminale(n : entier, acc : entier) : entier DEBUT SI n=0 ALORS RETOURNER acc SINON RETOURNER factorielleTerminale(n-1,acc*n) FIN ``` #### Est ce bien Terminé ? --- # La récursivité ## La factorielle en terminal ``` FONCTION factorielleTerminale(n : entier, acc : entier) : entier DEBUT SI n=0 ALORS RETOURNER acc SINON RETOURNER factorielleTerminale(n-1,acc*n) FIN ``` #### Est ce bien terminé ? NONNNNNNNNNNNNNNNN --- # La récursivité ## La factorielle en terminal ``` FONCTION factorielleTerminale(n : entier, acc : entier) : entier DEBUT SI n=0 ALORS RETOURNER acc SINON RETOURNER factorielleTerminale(n-1,acc*n) FIN ``` #### Est ce bien Terminé ? NONNNNNNNNNNNNNNNN ## POURQUOI ? Lorsqu'on appel la fonction la première fois ``` factorielleTerminale(4,1) factorielleTerminale(5,1) ``` .underR[Ce n'est pas beau !!!] --- # La récursivité ## MOCHE Lorsqu'on appel la fonction la première fois ``` factorielleTerminale(4,1) factorielleTerminale(5,1) ``` ## JOLI Lorsqu'on appel la fonction la première fois ``` factorielleTerminale(4) factorielleTerminale(5) ``` --- # La récursivité ## JOLI Lorsqu'on appel la fonction la première fois ``` factorielleTerminale(4) factorielleTerminale(5) ``` ## COMMENT ? - Avec une fonction intermédiaire - Il en faudra deux ! --- # La récursivité ## La même d'avant ```c FONCTION factorielleTerminaleCache(n : entier, acc : entier) : entier DEBUT SI n=0 ALORS RETOURNER acc SINON RETOURNER factorielleTerminaleCache(n-1,acc*n) FIN ``` ## C'est que l'utilisateur appelera ```c FONCTION factorielleTerminale(n : entier) : entier DEBUT RETOURNER factorielleTerminaleCache(n,1) FIN ``` ## L'appel ``` factorielleTerminale(4) factorielleTerminale(5) ``` --- # La récursivité ## Les problèmes de performance Parfois, on se retrouve avec des appels récursifs exponentiels ## Le classique FIBONACCI
--- # La récursivité ## Fibonacci non terminal
## Fibonacci \\[ F(n) = F(n-1) + F(n-2) \\] --- # La récursivité ## Fibonacci .pull-left[ | F | res | | -- | --- | | 0 | 0 | | 1 | 1 | | 2 | 1 | | 3 | 2 | | 4 | 3 | | 5 | 5 | | 6 | 8 | | 7 | 13 | | 8 | 21 | | 9 | 34 | | 10 | 55 | | 11 | 89 | ] .pull-right[
] --- # La récursivité ## Fibonacci non terminal ```c FONCTION FiboNonT(n : entier ) : entier DEBUT SI (n < 3) ALORS RETOURNER 1 SINON RETOURNER FiboNonT(n - 1) + FiboNonT(n - 2) FIN SI FIN ``` ## Le problème ! - Un arbre récursif trop important ! - On recalcule des choses qui ont déjà été calculées --- # La récursivité ## Fibonacci non terminal
--- # La récursivité ## VAR
Cette vidéo ne peut être affichée sur votre navigateur Internet.
Une version est disponible en téléchargement sous
adresse du lien
.
#### Mais comment faire ? - Récursivité terminal - Calculer la suite petit à petit ! --- # La récursivité ## Fibonacci en terminal ``` FONCTION FiboT(n : entier, acc1 : entier, acc2 : entier) : entier DEBUT SI (n = 0) ALORS RETOURNER acc2 SINON RETOURNER FiboT(n - 1, acc2, acc1+acc2) FIN SI FIN ``` --- # La récursivité ## Fibonacci en terminal .pull-left[ ``` FONCTION FiboT(n : entier, acc1 : entier, acc2 : entier) : entier DEBUT SI (n = 0) ALORS RETOURNER acc2 SINON RETOURNER FiboT(n - 1, acc2, acc1+acc2) FIN SI FIN ``` ] .pull-right[
] --- # La récursivité ## Fibonacci en terminal
--- # La récursivité ## Fibonacci en terminal
--- # La récursivité ## Fibonacci en terminal
--- # La récursivité ## Fibonacci en terminal
--- # La récursivité ## Fibonacci en terminal
--- # La récursivité ## VAR
Cette vidéo ne peut être affichée sur votre navigateur Internet.
Une version est disponible en téléchargement sous
adresse du lien
.
--- ## Types de récursivité - Une fonction récursive peut être simple ou multiple (cf fibonacci) ; - Une fonction récursive peut être terminale ou non terminale ; - Une fonction récursive peut être croisée ; - Dans tous les cas, une fonction récursive doit se terminer !! --- # Sitographie ## Quelques liens -
Openclass room
-
je suis un dev
-
lecluse nsi
-
cermics enpc