Vous êtes sur la page 1sur 16

Drcursivation

Drcursiver, cest transformer un algorithme


rcursif en un algorithme quivalent ne contenant
pas dappels rcursifs.

Rcursivit terminale
Dfinition Un algorithme est dit rcursif terminal
sil ne contient aucun traitement aprs un appel
rcursif.

Rcursivit terminale
Exemple :
ALGORITHME P(U)
si C(U)
alors
D(U);P(a(U))
sinon T(U)

o :

U est la liste des paramtres ;


C(U) est une condition portant sur U ;

D(U) est le traitement de base de lalgorithme


(dpendant de U) ;
a(U) reprsente la transformation des paramtres ;

T(U) est le traitement de terminaison (dpendant de U).

Rcursivit terminale
Avec ces notations, lalgorithme P quivaut
lalgorithme suivant :
ALGORITHME P(U)
tant que C(U) faire D(U);U a(U)

T(U)

Lalgorithme P est une version drcursive de


lalgorithme P.

Rcursivit non terminale


Ici, pour pouvoir drcursiver, il va falloir
sauvegarder le contexte de lappel rcursif,
typiquement les paramtres de lappel engendrant
lappel rcursif.

Originellement, lalgorithme est :


ALGORITHME Q(U)
si C(U) alors
D(U);Q(a(U));F(U)
sinon T(U)

Rcursivit non terminale


Utilisation de piles
Aprs drcursivation on obtiendra donc :
ALGORITHME Q(U)
empiler(nouvel_appel, U)
tant que pile non vide faire
dpiler(tat, V)

si tat = nouvel_appel alors U V


si C(U) alors D(U)
empiler(fin, U)
empiler(nouvel_appel, a(U))
sinon T(U)
si tat = fin alors U V
F(U)

Illustration de la drcursivation de
lalgorithme Q
Exemple dexcution de Q :
Appel Q(U0)
C(U0) vrai
D(U0)
Appel Q(a(U0))
C(a(U0)) vrai
D(a(U0))
Appel Q(a(a(U0)))

C(a(a(U0))) faux
T(a(a(U0)))
F(a(U0))

F(U0)

Exemple dexcution de lalgorithme


drcursiv.

Appel Q(U0)

empiler(nouvel_appel, U))

pile = [(nouvel_appel, U0)]


dpiler(tat, V))
tat nouvel_appel ; V U0 ; pile = []

U U0
C(U0) vrai
D(U0)

empiler(fin, U))
pile = [(fin, U0)]
empiler(nouvel_appel, a(U)))

pile = [(fin, U0) ; (nouvel_appel, a(U0))]

Exemple dexcution de lalgorithme


drcursiv.
dpiler(tat, V))
tat nouvel_appel ; V a(U0) ; pile = [(fin, U0)]
U a(U0)
C(a(U0)) vrai
D(a(U0))
empiler(fin, U))
pile = [(fin, U0) ; (fin, a(U0))]
empiler(nouvel_appel, a(U)))
pile = [(fin, U0) ; (fin, a(U0)) ; (nouvel_appel, a(a(U0)))]

Exemple dexcution de lalgorithme


drcursiv.
dpiler(tat, V))
tat nouvel_appel ; V a(a(U0)) ; pile = [(fin, U0) ; (fin, a(U0))]

U a(a(U0))
C(a(a(U0))) faux
T(a(a(U0)))

dpiler(tat, V))
tat fin ; V a(U0) ; pile = [(fin, U0)]
F(a(U0))

dpiler(tat, V))
tat fin ; V U0 ; pile = []
F(U0)

Drcursivation
Remarques

Les programmes itratifs sont souvent plus efficaces,

mais les programmes rcursifs sont plus faciles crire.

Les compilateurs savent, la plupart du temps,


reconnatre les appels rcursifs terminaux, et ceux-ci
nengendrent pas de surcot par rapport la version
itrative du mme programme.

Il est toujours possible de drcursiver un algorithme


rcursif.

ALGORITHME Q(U)

Exemple 1

si C(U) alors
D(U);Q(a(U));F(U)

Procedure ParcoursListe(a U :liste)


sinon T(U)
Debut
si(a<>nil) C(U)
alors begin
Q(a(U)); ParcoursListe(a^.suivant) ;
F(U) Ecrire(a^.info)
End
fsi
fin

U = a, C(U) = a<>nil, D(U) = vide a(U) = a^.suivant,


F(U) = ecrire(a^.info), T(U)= vide

Procedure parcoursListe (a :Liste)


var p: Liste
etat : (nouvel_appel, fin)
debut
empiler(nouvel_appel, a)
tant que pile non vide faire
dpiler(tat, p)
si tat = nouvel_appel alors a p
si a<>nil alors
empiler(fin, a)
empiler(nouvel_appel,a^.suivant)
fisi
fsi
si tat = fin alors a p
ecrire(a^.info)
fsi
ftantque
fin

procedure parcoursInfixe(a :Arbre)

ALGORITHME P(U)
si C(U)
alors
D(U);P(a(U))
sinon T(U)

debut
si (a<>nil)
parcoursInfixe(a^.fg)
ecrire(a^.info)
parcoursInfixe(a^.fd)
fsi

ALGORITHME P(U)
tant que C(U) faire
D(U);U a(U)
T(U)

fin

U = a, C(U)= a<>nil,
D(U) = {parcoursInfixe(a^.fg) , ecrire(a^.info)},
a(U)= a^.fd, T(U) = vide

Procedure ParcoursInfixe(a :Arbre)

debut
Tantque (a<>nil) faire
ParcoursInfixe(a^.fg)
Ecrire(a^.info)
a a^.fd
fintantque
fin

ALGORITHME Q(U)
si C(U) alors
D(U);Q(a(U));F(U)
sinon T(U)
U = a , C(U) = a<>nil, D(U) = vide,
a(U)=a^.fg, F(U) ={ecrire(a^.info), a=a^.fd} ,
T(U) =vide

Procedure parcoursInfixe(a :Arbre)


empiler(nouvel_appel, a)
tant que pile non vide faire
dpiler(tat, V)
si tat = nouvel_appel
alors a V
si a<>nil alors
empiler(fin, a)
empiler(nouvel_appel, a^.fg)
fsi
fsi
si tat = fin alors a V
ecrire(a^.info)
aa^.fd
empiler(nouvel_appel, a)
fsi
fintantque

Autre forme de rcurisivit non


terminale
Procdure Pi (U)
Procdure Pr (U)

dbut

dbut

initPileVide

tantque C(U) faire

tantque C(U) ou not pileVide faire

D(U)

tantque C(U) faire

Pr(a(U))

D(U)

F(U)

empiler(U)

fin tantque

U:= a(U)

fin

fin tant que


depiler (U)
F(U)
fin tantque
fin