Chapitre annexe. Récursivité

Slides:



Advertisements
Présentations similaires
Premier programme en C :
Advertisements

Introduction a L’algorithme
Tris.
Initiation à la programmation et algorithmique cours 2
Algorithmique (suite)
Portée des variables VBA & Excel
Fonctions & procédures
Introduction à l’Algorithmique
Calculs de complexité d'algorithmes
M. DELTA A ETE CHOISI CETTE ANNEE PAR LE RECTEUR POUR CORRIGER LEPREUVE DE MATHEMATIQUE DU DPECF (DIPLÔME PREPARATOIRE AUX ETUDES COMPTABLES ET FINANCIERE).
EXERCICE 2.1 : APRES AVOIR DEMANDE LA SAISIE DUN NOMBRE POSITIF (ERREUR DE SAISIE A TRAITER). AFFICHER LE DECOMPTE EN PARTANT DE CE NOMBRE JUSQUÀ ARRIVER.
DECLARATION DE VARIABLES
? ? En mémoire vive : I NB ALGORITHME EXERCICE 4 ETAPE 2 DEBUT
BUT DE LALGORITHME Afficher la table de multiplication dune valeur saisie au clavier (valeur comprise entre 1 et 9). Gérer lerreur de saisie.
Algorithmique et évaluation
Algorithmique Résume.
Les Structures de contrôles itératives
Problème de 8 dames: Sachant que dans un jeu des échecs, une dame peut pendre toute pièce se trouvant sur la colonne ou sur la ligne ou sur les diagonales.
Paramètres et pointeurs
INTRODUCTION.
5. Les structures répétitives
Les sous-programmes Chapitre n° 5: Objectifs : Activité:
Initiation à la programmation et algorithmique cours 3
Les structures de contrôles itératives complètes
Les requêtes La Requête est une méthode pour afficher les enregistrements qui répondent à des conditions spécifiques. La requête est donc un filtre.
Les bases de l’Algorithmique
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
Structures de données linéaires
Introduction à la programmation (420-PK2-SL) cours 12 Gestion des applications Technologie de linformation (LEA.BW)
Récursivité.
Démarche de résolution de problèmes
Dérécursivation Dérécursiver, c’est transformer un algorithme récursif en un algorithme équivalent ne contenant pas d’appels récursifs. Récursivité terminale.
Les éléments de base de l’algorithmique
Les algorithmes: complexité et notation asymptotique
Chapitre 1 PGCD de deux nombres.
Introduction - Modèle Discret – Modèle Continu - Algorithmes - Conclusion
Expression littérale  1) Définition
Algorithme de Bellman-Ford
Récursivité Définition récursive d’un problème. Critère d’arrêt et convergence. Performance des algorithmes récursifs. Résolution d’un problème à l’aide.
Les Fonctions. Définir une fonction Sections de code indépendantes que lon peut appeler à nimporte quel moment et dans nimporte quel ordre. Bout de code.
Introduction à la programmation I Fonctions Structures de contrôle Structures de données (arrays simples et indexés) Variables locales et globales.
Sixième cours Les chaînes de caractères et le passage de paramètres par référence Passage de paramètres par référence String.h.
Courbes de Bézier.
Génération d’un segment de droite
1 La récursion. Nous avons vu qu'un programme est constitué d'un ensemble de fonctions. Il est possible pour une fonction donnée d'appeler une autre fonction.
Chapitre 9 Les sous-programmes.
Algorithmique et programmation en gestion
Algorithmique et structures de données en C
Structures de données IFT-2000 Abder Alikacem La récursivité Semaine 5 Département dinformatique et de génie logiciel Édition Septembre 2009.
Programmation linéaire en nombres entiers : les méthodes de troncature
Structures de données IFT-2000 Abder Alikacem La récursivité Département d’informatique et de génie logiciel Édition Septembre 2009.
Exemple de gestion d'un buffer clavier en liste circulaire
RAPPEL Qu’est ce qu’une structure de contrôle itérative ?
Présentation de la méthode des Eléments Finis
1 Notations Asymptotiques Et Complexité Notations asymptotiques : 0 et  Complexité des algorithmes Exemples de calcul de complexité.
Ch. PAUL - Piles et Files à l'aide de listes chainées
LES PILES ET FILES.
INTRODUCTION.
CYCLE 6 : FONCTIONS Faire un programme en C avec des FONCTIONS 1- A quoi servent les FONCTIONS ? 2- Comment écrire un programme avec FONCTIONS ? 3- Comment.
Algorithmique et programmation (1)‏
Décomposition et paramétrage des algorithmes
Introduction au langage C Fonctions et Procédures
ISBN Chapitre 10 L'implémentation des sous- programmes.
Les algorithmes recursifs
Introduction à la récursivité
Introduction au langage C : Structures de contrôle 1 ère année Génie Informatique Dr Daouda Traoré Université de Ségou
2005/2006 Structures de Données Introduction à la complexité des algorithmes.
La récursivité Mireille Goud HEG Vd AlgSD - Résurisivité.
02/10/2015Les structures de contrôle1 COURS A2I12 Initiation à l'algorithmique illustrée par le langage C Guillaume BOURLET Département GEII IUT Sénart/Fontainebleau.
Algorithmique Boucles et Itérations
Transcription de la présentation:

Chapitre annexe. Récursivité

Introduction On a appris comment écrire des actions répétitives avec des boucles. Cette manière de traiter des actions répétitives s'appelle programmation itérative. Il existe un procédé concurrentiel à celle-ci: la récursivité. Tout processus répétitif peut être considéré de deux points de vue. Ainsi, pour monter un escalier de n marches on peut soit faire de 1 à n: monter une marche (approche itérative) soit monter une marche, puis monter un escalier de n –1 marches, ... Une fois l'escalier restant ne comporte que 0 marches, s'arrêter. (approche récursive).

Processus répétitifs : répétition "classique" et récurrence Donnons un exemple de processus répétitif exprimé de façon itérative et récursive. Une puissance n (n > 0) d'un réel x peut être programmée à l'aide d'une boucle pour:

données : float x, int n résultat de type float Entête en C : float puiss(float x, int n); {variables locales : float p, int i p  1 POUR (i  1 à n) FAIRE p  p*x retourner p }

Mais on peut également donner la recette suivante, qu'on va d'abord décrire. Pour faciliter l'écriture, appelons la fonction puissance f : Alors f(x,n)=f(x,n–1)x où f(x,n–1) est pour le moment inconnue, mais on peut la calculer comme f(x,n–1)=f(x,n–2)x où f(x,n–2) est pour le moment inconnue, mais on peut la calculer comme f(x,n–2)=f(x,n–3)x etc… En continuant, on arrive à ce que la fonction figurant dans le terme de droite est f(x,n–n)=f(n, 0)=x0=1. A ce point, elle n'est plus inconnue. Cela peut se programmer comme suit:

données : float x, int n résultat de type float Entête en C : float puis(float x, int n) {variables locales : float p SI (n = 0) ALORS {1: condition d'arrêt} p  1 SINON p  x * puis(x,n-1) {2: action répétée: multiplication par x} {3: appel récurrent de puis avec un paramètre modifié} retourner p }

Cette écriture n'est rien d'autre que le codage en C de la relation de récurrence: puissance (x,0) = 1 puissance(x,n) = puissance(x,n–1)*x si n > 0 Nous venons de donner un exemple de fonction récursive. A la différence des fonctions vues auparavant, elle comporte un appel à la même fonction (puissance). Cet appel se fait avec une nouvelle valeur de paramètre (n–1 au lieu de n).

Toute procédure ou fonction récursive comprend les 3 parties suivantes : 1. la condition d'arrêt du processus 2. l'action à répéter, donc à exécuter dans l'étape courante 3. le passage à l'étape suivante : on continue (appel récurrent) avec une nouvelle valeur du paramètre La répétition gérée à l’aide des boucles peut se considérer comme une vue globale d'un processus répétitif. La récurrence peut se considérer comme une vue locale d'un processus répétitif : étape n et passage à l'étape n+1, si on n'a pas fini. Ceci est possible pour tout processus répétitif.

Récursivité simple Définition Un algorithme sp est récursif, si lors de son exécution, on doit à nouveau lancer l'exécution de sp.

Exemples Placer 10 étoiles sur une ligne à l'écran

Version non-récursive : Entête en C : void etoiles_non_rec() {variables locales : int i POUR (i  1 à 10) FAIRE écrire (‘*’) } Appel dans l’algorithme appelant : . etoiles_non_rec()

Version récursive : données : int n Entête en C : void etoiles_rec (int n); { SI (n  10) ALORS écrire (‘*’) etoiles_rec(n+1) } Appel dans l’algorithme appelant : . etoiles_rec(1)

À l'appel de tout module (récurrent ou non), les valeurs des variables locales de ce module sont placées en mémoire centrale en haut d'une pile (tout à fait comparable avec une pile d'assiettes), sur celles du module qui l'a appelé, à partir des valeurs des variables du programme principal, qui constituent la base de la pile. Chaque fois que l'exécution d'un module est terminée, les valeurs de ses variables locales sont supprimées en haut de la pile (on dit: "dépilées").

En cas d'appel récurrent, il se produit exactement la même chose: Un module récurrent appelle un nouvel exemplaire de lui-même, dont les nouvelles valeurs des variables locales s'empilent en mémoire.

Par conséquent, une répétition exprimée par récurrence occupe en mémoire une place proportionnelle au nombre de répétitions, alors qu'une répétition "classique" occupe une place indépendante du nombre de répétitions. En conclusion, on choisit la récursivité seulement si l'écriture est plus simple, et si le nombre maximum de modules empilés est faible (sauf en langage Lisp, où toute répétition s'exprime par récurrence).

Afficher les 10 premiers nombres entiers à l'écran: Version non-récursive : Entête en C : void compter_rep () {variables locales : int i POUR (i  1 à 10) FAIRE afficher(i) }

Version récursive : données : int n  Entête en C : void compter_rec(int n) { SI (n  10) ALORS afficher(n) compter_rec(n+1) }

Si l'on place une autre action à répéter après l'appel récurrent, cette action ne se fait pas à l'empilement, mais au dépilement: On empile les modules (imaginez la pile de modules comme une pile d'assiettes): dans le premier (bas de la pile), n a pour valeur 1 dans le dernier (haut de la pile), n a pour valeur 10

On dépile les modules: on affiche la valeur de n du premier module dépilé (haut de la pile): 10 puis on affiche la valeur de n du deuxième module dépilé (haut de la pile): 9 et ainsi de suite: on affiche donc les nombres décroissants On parcourt la pile en touchant 2 fois chaque assiette : 1 fois à l'empilement, 1 fois au dépilement

données : int n  Entête en C : void compterRecur (int n) { SI (n <= 10) ALORS afficher('empilement: ', n); compterRecur(n + 1); afficher('dépilement : ', n) }

empilement : 1 empilement : 2 empilement : 3 empilement : 4 empilement : 5 empilement : 6 empilement : 7 empilement : - 8 empilement : 9 empilement : 10 dépilement : 10 dépilement : 9 dépilement : 8 dépilement : 7 dépilement : 6 dépilement : 5 dépilement : 4 dépilement : 3 dépilement : 2 dépilement : 1

Définition Un sous-algorithme est dit récursif terminal s'il n'y aura aucun calcul à faire à la sortie de la relance récursive pour obtenir le résultat final

Calculer la somme des n premiers nombres entiers Version non-récursive en C : int somme_iter (int n) { int i , som = 0 ; for (i = 1 ; i <= n ; i++) som = som + i ; return som ; }

Version récursive : En fait, cette fonction n'est que le codage en C de la relation de récurrence : somme(1) = 1 somme(n) = somme (n – 1) + n si n > 1 int SommeRecur (int n) { int somme; printf (" empilement : %d \n", n); if (n = 1) { printf (" depilement : %d \n", n); return 1 ; } else somme = n + SommeRecur(n – 1); printf (" depilement : %d \n", n); return somme ; }

Appel : . som = SommeRecur(10); printf ("som: %d \n", som);

empilement : 10 empilement : 9 empilement : 8 empilement : 7 empilement : 6 empilement : 5 empilement : 4 empilement : 3 empilement : 2 empilement : 1 dépilement : 1 dépilement : 2 dépilement : 3 dépilement : 4 dépilement : 5 dépilement : 6 dépilement : 7 dépilement : 8 dépilement : 9 dépilement : 10 som : 55

Circulation des données entre les différentes instances de SommeRecur: 55 <-- 45 <--36 <-- 28 <-- 21 <-- 15 <-- 10 <-- 6 <-- 3 <-- 1 SommeRecur(n)

Récursivité croisée II arrive parfois qu'un algorithme soit constitué de deux sous-algorithmes récursifs dont les définitions s'entrecroisent mutuellement.

Définition On dira que l’on a une récursivité croisée quand on a deux sous-algorithmes sp1 et sp2 tels que lors de l'exécution de sp1, on doit lancer l'exécution de sp2, et inversement.

L'exemple classique de récursivité croisée est donné par le calcul de la parité d'un entier en C : int pair(int n) /* Pour n  0, pair(n) est vrai si n est pair et faux sinon */ { if (n == 0) pair = 1; else return ( impair(n-1) ); } int impair(int n) ; /* Pour n  0, impair(n) est vrai si n est impair et faux sinon */ { if (n = =0) impair = 0; else return (pair(n-1)); }

Récursivité multiple Terminons par une catégorie de programmes récursifs qui mettra le plus en lumière la puissance du procédé : la récursivité multiple.

Définition On dira qu'il y a une récursivité multiple (double, triple, ... ) dans un sous-algorithme sp si, lors de son exécution, il faudra plusieurs relances récursives conjointes de sp pour obtenir le résultat final

L'exemple très simple c'est le calcul du terme d'ordre n de la suite de Fibonacci, définie par : F(n) = F(n-1) + F(n-2) F(1) = 1 F(2) = 1 En C : int fibo(int n) { if (n <=2) return 1; return fibo(n-1) + fibo(n-2); }