Cours Algorithmique, 2ème partie AS IUT Cours 1 : Listes récursives Anne Vilnat http://www.limsi.fr/Individu/anne/coursAlgo Plan 1 Introduction à la récursivité 2 Définition d’une liste récursive Définition de la classe ListeRecursive Utilisation 3 Récursion “ascendante/descendante” 4 Récursion “ascendante” Exemple 1 : Inverser une lise Exemple 2 : Somme d’une liste récursive Exemple 3 : Tester si une liste récursive est strictement croissante Finissons par un mystère... Les listes : définition “large” Définition Une liste permet de ranger un nombre quelconque d’éléments, sans connaı̂tre à l’avance leur nombre. Vision récursive Définition récursive d’une liste Définition Une liste c’est soit une liste vide soit une cellule suivie d’une liste Définition récursive car une liste est définie par une liste. la première partie de la définition (“soit une liste vide”) assure l’arrêt et donc la cohérence de la définition. Définition de la classe ListeRecursive Classe ListeRecursive Attributs : non explicités {vous êtes utilisateurs de la classe} Méthodes : fonction fonction fonction fonction vide() tête() reste() préfixer(val) {vrai si la liste est vide} {valeur enregistrée dans la tête} {liste obtenue en enlevant la tête} {liste obtenue en insérant val en tête} Méthodes de la classe ListeRecursive Spécifications des méthodes fonction vide() retourne booléen {Retourne vrai si la liste est vide, faux sinon} Paramètre Cible : ListeRecursive (E) fonction tête() retourne INFO {Retourne la valeur enregistrée dans la tête. Erreur si la liste est vide.} Paramètre Cible : ListeRecursive (E) fonction reste() retourne ListeRecursive {Retourne la liste obtenue en enlevant la tête. Erreur si la liste est vide.} Paramètre Cible : ListeRecursive (E) fonction préfixer(val) retourne ListeRecursive {Retourne la liste obtenue en insérant val en tête} Paramètre Cible : ListeRecursive (E) val : INFO (E) Affichage d’une ListeRecursive Afficher une liste procédure afficherListe(uneListe) {Affiche les valeurs contenues dans une liste.} paramètre uneListe : ListeRecursive (E) début si non uneListe.vide() {test d’arrêt} alors écrire(uneListe.tête()) {traitement} afficherListe(uneListe.reste()) {appel récursif } fsi fin Affichage d’une ListeRecursive Récursion “descendante” Principes Récursion terminale (”fausse” récursion) Rien au retour de l’appel récursif Traitement suivi de l’appel récursif Données n’ont pas besoin d’être stockées Version itérative possible → ce qu’on vient de faire Affichage dans l’ordre inverse Afficher une liste dans l’ordre inverse procédure afficherInverse(uneListe) {Affiche les valeurs contenues dans une liste dans l’ordre inverse.} paramètre uneListe : ListeRecursive (E) début si non uneListe.vide() {test d’arrêt} alors afficherInverse(uneListe.reste()) {appel récursif } écrire(uneListe.tête()) {traitement} fsi fin Affichage d’une ListeRecursive Récursion “ascendante” Principes Récursion non terminale Exécution d’une action au retour de l’appel récursif Appel récursif suivi d’un traitement Données ont besoin d’être stockées Version itérative beaucoup plus difficile → ce qu’on vient de faire dans l’affichage inverse Exemple : inverser une liste Principe Cas général : Enlever la tête Inverser le reste de la liste (appel récursif) Rajouter la tête en fin de liste Cas particulier : Liste vide : ne rien faire (condition d’arrêt) Algorithme de inverser une liste Inverser une liste fonction inverser(uneListe) retourne listeRecursive {Retourne la liste inverse de la liste passée en paramètre.} paramètre uneListe : ListeRecursive (E) variables premier : INFO nouvListe : listeRecursive début si uneListe.vide() {test d’arrêt} alors retourner(uneListe) sinon premier := uneListe.tete() nouvListe := inverser (uneListe.reste()) ajoutQueue(premier, nouvListe) retourner(nouvListe) fsi fin Autre version de inverser une liste Inverser une liste fonction inverser(uneListe) retourne listeRecursive {Retourne la liste inverse de la liste passée en paramètre.} paramètre uneListe : ListeRecursive (E) début si uneListe.vide() {test d’arrêt} alors retourner(uneListe) sinon retourner(inverser(uneListe.reste()).ajoutQueue(uneListe.tete())) fsi fin Algorithme de ajoutQueue Ajouter en queue d’une liste fonction ajoutQueue(uneVal,uneListe) retourne listeRecursive {Retourne la liste résultant de l’ajout de uneVal en queue de uneListe} paramètre uneVal : INFO (E) uneListe : ListeRecursive (E) début si uneListe.vide() {test d’arrêt} alors retourner(uneListe.prefixer(uneVal) sinon retourner(ajoutQueue(uneVal,uneListe.reste()). prefixer(uneListe.tete())) fsi fin Somme des éléments d’une liste Sommer les éléments d’une liste fonction sommer(uneListe) retourne entier {Retourne la somme des entiers enregistrés dans une liste} paramètre uneListe : ListeRecursive (E) début si uneListe.vide() {test d’arrêt} alors retourner(0) sinon {Cas général} retourner(uneListe.tete() + sommer(uneListe.reste())) fsi fin Tester si les éléments d’une liste sont strictement croissants Tester l’ordre des éléments d’une liste fonction sCroissante(uneListe) retourne booléen {Teste si une liste d’entiers est strictement croissante} paramètre uneListe : ListeRecursive (E) début si uneListe.vide() alors retourner VRAI si uneListe.reste().vide() alors retourner VRAI si (uneListe.tete() < uneListe.reste().tete()) alors retourner sCroissante(uneListe.reste()) sinon retourner FAUX fsi fin Une fonction mystère... ???? fonction mystere(l1,l2) retourne booléen {Que fait-elle???????? } paramètre l1,l2 : ListeRecursive (E) début si l1.vide() alors si l2.vide() alors retourner VRAI sinon si l2.tete() = 0 alors retourner mystere(l1,l2.reste()) sinon retourner FAUX si l1.tete() = 0 alors retourner mystere(l1.reste(),l2) si l2.vide() alors retourner FAUX si l2.tete() = 0 alors retourner mystere(l1,l2.reste()) si l1.tete() = l2.tete() alors retourner mystere(l1.reste(),l2.reste()) retourner FAUX fin