Вы находитесь на странице: 1из 38

IFT-1004 - Introduction la programmation

Rcursivit
Jean-Francis Roy
Dpartement dinformatique et de gnie logiciel
Universit Laval

Module 10

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

1 / 38

Table des matires

Les algorithmes rcursifs

Les problmes dfinis rcursivement

Les structures de donnes rcursives

Lectures et travaux dirigs

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

2 / 38

La rcursivit

Objectif
Sintroduire un concept fondamental en programmation, la
rcursivit, en solutionnant des problmes de manire rcursive, puis
en explorant certains problmes et certaines structures de donnes qui
sont dfinis rcursivement.

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

3 / 38

Plan

Les algorithmes rcursifs

Les problmes dfinis rcursivement

Les structures de donnes rcursives

Lectures et travaux dirigs

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

4 / 38

Introduction

Plusieurs problmes sont rsolus de manire rcursive parce quils


sont naturellement dcrits de faon rcursive (induction). En
mathmatiques entre autres : calcul de la factorielle, la suite de
Fibonacci, le problme du plus grand commun diviseur (PGCD), etc.
La rsolution du problme est simplifie dans ces cas.
Diviser pour rgner : r-appliquer un mme traitement sur un
chantillon de donnes dune taille de plus en plus petite.
En informatique, la programmation avance utilise souvent des
techniques de programmation rcursive.

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

5 / 38

Dfinition

Soit une fonction comprenant un appel elle-mme, soit directement,


soit indirectement. Alors, est une fonction rcursive.
Rcursivit directe : une fonction comporte, dans sa dfinition, au
moins un appel elle-mme.
def f_1 (...):
...
x = f_1 (...)
...
return x

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

6 / 38

Structure gnrale
def fonction (...):
# Vrification des conditions de convergence
i f ...:
r a i s e Exception (...)
# Vrification des conditions d'arrt
i f ...:
r e t u r n ...
# Appel (s) rcursif (s)
x = fonction (...)
# Retour
return x

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

7 / 38

Diviser pour rgner

Les algorithmes de type diviser pour rgner divisent le problme en


un sous-problme du mme type (rsolu par le mme algorithme),
jusqu ce que le problme soit si simple quon en connat dj la
solution.

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

8 / 38

Diviser pour rgner : la somme dune liste


Ide : Pour calculer la somme des lments dune liste de lments, il
sagit dadditionner le premier lment la somme des 1
lments du reste de la liste.
Rcursion : ([0], [1], , [ 1]) = [0] + ([1], , [ 1])
Condition darrt : ([0]) = [0] (un seul terme additionner)
Convergence : Pour tout > 1, dcrot de 1 chaque appel rcursif.
On a donc convergence pour 0.

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

9 / 38

Diviser pour rgner : la somme dune liste

def somme( liste ):


# Conditions d'arrt
i f len (liste ) == 0:
return 0
i f len (liste ) == 1:
r e t u r n liste [0]
# Appel rcursif et retour
r e t u r n liste [0] + somme ( liste [1:])

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

10 / 38

La somme dune liste : trace des appels

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

11 / 38

La somme dune liste : version non rcursive

def somme( liste ):


la_somme = 0
f o r element in liste :
la_somme += element
r e t u r n la_somme

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

12 / 38

Diviser pour rgner : le palindrome

Rappel : un palindrome est un mot qui peut tre lu de la mme


manire de gauche droite ou de droite gauche.
Ide : Un mot est un palindrome si son premier et son dernier
caractres sont les mmes, et si la partie lintrieur du mot est
un palindrome.

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

13 / 38

Diviser pour rgner : le palindrome


Rcursion : chaine est un palindrome si :
chaine[0] == chaine[-1]
chaine[1:-1] est un palindrome

Conditions darrt :
1

la chane na aucun caractre VRAI

la chane a un seul caractre VRAI

Si chaine[0] != chaine[-1] FAUX

Convergence : Une chane a ncessairement une longueur 0. Sa


longueur diminue de 2 chaque appel rcursif pour len(chaine) 2.
On a donc convergence pour len(chaine) 0.
IFT-1004 - Introduction la programmation

Rcursivit

Module 10

14 / 38

Diviser pour rgner : le palindrome

def est_palindrome ( chaine ):


# Conditions d'arrt
i f len ( chaine ) <= 1:
r e t u r n True
i f chaine [0] != chaine [ -1]:
r e t u r n False
# Appel rcursif et retour
r e t u r n est_palindrome ( chaine [1: -1])

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

15 / 38

Le palindrome : trace des appels

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

16 / 38

Le palindrome : version non rcursive

def est_palindrome ( chaine ):


# Conditions d'arrt
i f len ( chaine ) <= 1:
r e t u r n True
f o r i in range ( len ( chaine ) // 2):
i f chaine [i] != chaine [-i -1]:
r e t u r n False
r e t u r n True

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

17 / 38

Diviser pour rgner : la factorielle


Rappel : la factorielle dun nombre , nomme !, est dfinie par le
produit 1 2 3
Ide : La factorielle dun nombre est le produit entre et la factorielle
du nombre 1.
Rcursion : () = ( 1)
Conditions darrt : Par dfinition, 0! = 1! = 1.
Convergence : Pour tout 2, la soustraction par 1 nous amnera vers
la condition darrt. On a donc convergence pour 0.
IFT-1004 - Introduction la programmation

Rcursivit

Module 10

18 / 38

Diviser pour rgner : la factorielle

def factorielle (n):


# Condition de convergence :
i f n < 0:
r a i s e ValueError ("Non convergence ")
# Conditions d'arrt :
i f n == 0 or n ==1:
return 1
# Appel rcursif et retour
r e t u r n n * factorielle (n - 1)

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

19 / 38

Le factorielle : trace des appels

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

20 / 38

La factorielle : version non rcursive

def factorielle (n):


# Condition de convergence :
i f n < 0:
r a i s e ValueError ("Non convergence ")
resultat = 1
f o r i in range (2, n+1):
resultat *= i
r e t u r n resultat

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

21 / 38

Plan

Les algorithmes rcursifs

Les problmes dfinis rcursivement

Les structures de donnes rcursives

Lectures et travaux dirigs

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

22 / 38

La suite de Fibonacci
La suite de Fibonacci est une suite de nombres trs tudie en
mathmatiques. Elle a t nomme en lhonneur de Leonardo Bonacci
(aussi connu sous plusieurs autres noms dont Leonardo Pisano).
Chaque terme de cette suite (sauf les deux premiers) sont obtenus en
additionnant les deux termes prcdents : 0, 1, 1, 2, 3, 5, 8, 13, ....
Rcursion : () = ( 1) + ( 2)
Conditions darrt : (0) = 0, (1) = 1
Convergence : Pour tout 2, nous faisons deux appels rcursifs avec
de plus petites valeurs de , jusqu ce que soit gal 0 ou 1. On a
donc convergence pour 0.
IFT-1004 - Introduction la programmation

Rcursivit

Module 10

23 / 38

La suite de Fibonacci

def fibonacci (n):


# Condition de convergence :
i f n < 0:
r a i s e ValueError ("Non convergence ")
# Conditions d'arrt :
i f n == 0 or n ==1:
return n
# Appel rcursif et retour
r e t u r n fibonacci (n - 2) + fibonacci (n - 1)

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

24 / 38

Le suite de Fibonacci : trace des appels

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

25 / 38

Les tours de Hano

Le jeu mathmatique des tours de Hano consiste dplacer une tour


de disques dune ple vers une autre ple, en ayant accs une ple
intermdiaire. Les rgles sont les suivantes :
On ne peut transfrer quun seul disque la fois
Les disques ont des diamtres diffrents
aucun moment, un disque de diamtre suprieur ne peut
reposer sur un disque de diamtre infrieur.
IFT-1004 - Introduction la programmation

Rcursivit

Module 10

26 / 38

Les tours de Hano

Pour un certain nombre de disques , le problme est soluble si nous


sommes capables daccomplir les actions suivantes :
1

Dplacer rcursivement 1 disques de la tour source vers la


tour intermdiaire
Dplacer le disque restant de la tour source vers la tour de
destination
Dplacer les 1 disques de la tour intermdiaire vers la tour de
destination

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

27 / 38

Les tours de Hano

def hanoi(n, source , auxiliaire , destination ):


i f n <= 0:
r a i s e ValueError (" Erreur !")
i f n == 1:
p r i n t (" Dplacer {} vers {}". format (source ,
destination ))
else :
hanoi(n - 1, source , destination , auxiliaire )
p r i n t (" Dplacer {} vers {}". format (source ,
destination ))
hanoi (n - 1, auxiliaire , source , destination )

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

28 / 38

Plan

Les algorithmes rcursifs

Les problmes dfinis rcursivement

Les structures de donnes rcursives

Lectures et travaux dirigs

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

29 / 38

Les structures de donnes rcursives

Soit un objet comprenant une instance de lui-mme. Alors est une


structure rcursive.

c l a s s Tata:
def __init__ ( s e l f , n):
s e l f .n = n
i f n != 0:
s e l f . suivant = Tata(n - 1)
else :
s e l f . suivant = None

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

30 / 38

Les structures de donnes rcursives


Liste chane :

12

99

37

Arbre binaire (de recherche) :

8
3
1

6
4

IFT-1004 - Introduction la programmation

10
14
7
Rcursivit

13
Module 10

31 / 38

Les listes chanes en python


c l a s s Noeud:
def __init__ ( s e l f , donnee ):
s e l f . donnee = donnee
s e l f . suivant = None

c l a s s ListeChainee :
def __init__ ( s e l f ):
s e l f . noeud_courant = None
def inserer ( s e l f , donnee ):
nouveau_noeud = Noeud ( donnee )
nouveau_noeud . suivant = s e l f . noeud_courant
s e l f . noeud_courant = nouveau_noeud

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

32 / 38

Les listes chanes en python

12

99

37

lc = Listechainee ()
lc. inserer (37)
lc. inserer (99)
lc. inserer (12)
p r i n t (lc. noeud_courant . donnee )
p r i n t (lc. noeud_courant . suivant . donnee )
p r i n t (lc. noeud_courant . suivant . suivant . donnee )

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

33 / 38

Les arbres binaires en python


c l a s s NoeudArbreBinaire :
def __init__ ( s e l f , donnee ):
s e l f . donnee = donnee
s e l f . gauche = None
s e l f . droite = None

c l a s s ArbreBinaireDeRecherche :
def __init__ ( s e l f ):
s e l f . racine = None
def inserer ( s e l f , donnee ):
s e l f . racine = s e l f . _inserer_recursif ( s e l f .racine ,
donnee )
[...]

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

34 / 38

Les arbres binaires en python


[...]
def _inserer_recursif ( s e l f , racine , donnee ):
nouveau_noeud = NoeudArbreBinaire ( donnee )
i f racine == None:
r e t u r n nouveau_noeud
else :
i f donnee <= racine . donnee :
racine . gauche = \
s e l f . _inserer_recursif ( racine .gauche ,
donnee )
else :
racine . droite = \
s e l f . _inserer_recursif ( racine .droite ,
donnee )
r e t u r n racine

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

35 / 38

La rcursivit en bref
La rcursion nest pas une panace (remde universel) : si on peut
aisment la remplacer par une boucle, il vaut mieux le faire
On peut lutiliser quand on a besoin dun gain en performance
possible grce une formulation rcursive habile
La rcursion permet galement de traiter des structures
arbitraires, ce qui est impossible avec des boucles imbriques, car
on ne peut pas prdire combien de boucles seront ncessaires
Supposons que lon veut rcursivement sommer les lments
dune liste de listes de listes, etc...
def somme (liste ):
resultat = 0
f o r element in liste :
i f i s i n s t a n c e (element , liste ):
resultat += somme(liste)
else :
resultat += element
IFT-1004 - Introduction la programmation

Rcursivit

Module 10

36 / 38

Plan

Les algorithmes rcursifs

Les problmes dfinis rcursivement

Les structures de donnes rcursives

Lectures et travaux dirigs

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

37 / 38

Lectures et travaux dirigs

Aucune lecture
Travaux dirigs : Exercices sur la rcursivit

IFT-1004 - Introduction la programmation

Rcursivit

Module 10

38 / 38

Вам также может понравиться