Récursivité

Fermé
kimodev Messages postés 10 Date d'inscription mardi 17 mai 2011 Statut Membre Dernière intervention 18 mai 2011 - 17 mai 2011 à 13:23
kimodev Messages postés 10 Date d'inscription mardi 17 mai 2011 Statut Membre Dernière intervention 18 mai 2011 - 18 mai 2011 à 21:11
Bonjour,

bah c ma 1ere participation sur ce forum et j'espere ne pas etre un peu énervant pour vous
j'ai besoin de votre aie pour comprenre l'execution de la recursivité pas à pas,ans ce petit code ci joint
ca se compile bien mais pour suivre les étapes,c difficile pour surtout que je ss un débutant dans ce domaine
merci à vs


#include <stdio.h>
void deplacer (int n, int t1, int t2, int t3)
{
if ( n == 1 )
printf("De la tour %d à la tour %d\n", t1, t2) ;
else
{ deplacer (n-1, t1, t3, t2) ;
deplacer ( 1 , t1, t2, t3) ;
deplacer (n-1, t3, t2, t1) ;
}
}
int main()
{
deplacer(3,1,3,2);
return 0;
}



4 réponses

Ci-dessous, je te décris l'appel au premier niveau, puis le niveau intermédiaire, et enfin la totale

premier niveau :
deplacer (3,1,3,2) 
  n=3, t1=1, t2=3, t3=2 
  deplacer (2,1,2,3) (A) 
  deplacer (1,1,3,2) 
  deplacer (2,2,3,1) (B) 

second niveau:
Mais pour faire (A) deplacer (2,1,2,3) (n=2,t1=1,t2=2,t3=3) il faut faire 
  deplacer (1,1,3,2) 
  deplacer (1,1,2,3) 
  deplacer (1,3,2,1) 

Et pour faire (B) deplacer (2,2,3,1) (n=2, t1=2,t2=3,t3=1) il faut faire 
  deplacer (1,2,1,3) 
  deplacer (1,2,3,1) 
  deplacer (1,1,3,2) 


synthèse :
deplacer (3,1,3,2) 
  deplacer (2,1,2,3) 
    deplacer (1,1,3,2) 
    deplacer (1,1,2,3) 
    deplacer (1,3,2,1) 
  deplacer (1,1,3,2) 
  deplacer (2,2,3,1)  
    deplacer (1,2,1,3) 
    deplacer (1,2,3,1) 
    deplacer (1,1,3,2) 
1
sudoer Messages postés 113 Date d'inscription lundi 9 mai 2011 Statut Membre Dernière intervention 11 juin 2011 14
17 mai 2011 à 13:32
Bonjour, tu as oublié les accolades après le if :

if ( n == 1 )
printf("De la tour %d à la tour %d\n", t1, t2) ;
else

correction :
if ( n == 1 )
{
printf("De la tour %d à la tour %d\n", t1, t2) ;
}
else


Pour le reste, il faudrait que tu nous dise ce que tu veux faire exactement.
0
kimodev Messages postés 10 Date d'inscription mardi 17 mai 2011 Statut Membre Dernière intervention 18 mai 2011
17 mai 2011 à 13:38
ce que je veux c comprendre la compilation de ce programme,càd,lorsqu'on a 3 disques par exemple est ce que ce le programme execute la partie de else? si oui alors comment ca se passe vraiment parc que ave les (n-1) j'arrive avec le n de disques à 0 et voilà je ne sais pas comment ca se fonctionne
0
Bonjour

Non, tu n'as pas oublié d'accolades. Elles sont inutiles puisque tu n'as qu'une seule instruction après le if
L'enchaînement est un peu compliqué. Si je ne me suis pas trompé
deplacer (3,1,3,2)  
  deplacer (2,1,2,3)  
    deplacer (1,1,3,2)  
    deplacer (1,1,2,3)  
    deplacer (1,3,2,1)  
  deplacer (1,1,3,2)  
  deplacer (2,2,3,1)  
    deplacer (1,2,1,3)  
    deplacer (1,2,3,1)  
    deplacer (1,1,3,3)  

Le principe est de
Déplacer N-1 disques de la tour de départ vers la tour intermédiaire
Déplacer 1 disque de la tour de départ vers la tour d'arrivée
Déplacer N-1 disques de la tour intermédiaire vers la tour d'arrivée.

Tu trouveras des exemples animés avec google en cherchant "Tours de Hanoï"
0
kimodev Messages postés 10 Date d'inscription mardi 17 mai 2011 Statut Membre Dernière intervention 18 mai 2011
17 mai 2011 à 14:07
bah oui je sais le probleme c pas avec le code il fonctionne bien c juste que je n'ai pas compris sa logique ( :s)
0
Tu avais sans doute répondu avant que je ne complète ma réponse.
Tu peux essayer d'y jouer avec n'importe quoi, de simples bouts de papiers numérotés 1,2,3 et 3 cercles sur une feuille suffisent.
Rien de tel que de la faire à la main
0
kimodev Messages postés 10 Date d'inscription mardi 17 mai 2011 Statut Membre Dernière intervention 18 mai 2011
17 mai 2011 à 14:23
oui je vois,mais s q entre chaque deplacer et deplacer on return à cette instruction printf("De la tour %d à la tour %d\n", t1, t2) ; ????
si oui alors comment et la condition dit que n==1
0
cap'tain sheeps
17 mai 2011 à 14:36
Le principe des fonction récursive, c'est qu'elles s'appellent elles-mêmes tant qu'une condition n'est pas remplie.
Pour l'expliquer de manière plus simple, avec un exemple:
il faut imaginer une boite avec à l'interrieure une série de boites plus petites, jusqu'à ce que tu trouves une surprise (et une surprise vraiment cool, crois moi...)
Bref à chaque fois, tu va appeller une fonction qu'on nommera ouvrirBoite() et qui aura pour corps la découverte de ce qu'il y a à l'interrieur et si c'est une autre boite, on devra à nouveau appeller un ouverture de boite. Ce qui te donnera un algorithme comme ceci:

ouvrirBoite() //ici on défini la fonction qui ouvre la boite
{
interrieur = decouvrirCeQuIlYADedans(); // on regarde ce qu'il y a à l'interrieur
if ( interrieur != megaSurprise) // si ce n'est pas la surprise c'est une autre boite
{
ouvrirBoite();
/*donc on refet appel à la fonction qui va ouvrir la boite, regarder dedans et si c'est une autre boite on l'ouvrira encore et encore et etc*/
else
{
WowQuelMagnifiqueSurprise // jusqu'à ce que tu découvre ta magnifique surprise
}
}

Dans ton exemple, c'est pareil. La surprise que tu attends c'est que ta variable n soit égale à 1 (oui il y a des suprises meilleures que d'autres)
Donc à chaque fois, tu vas faire appel à la fonction deplacer, qui va s'appeller elle-même jusqu'à arriver à son but. Elle va donc modifier les valeurs de tes variables de la manière dont le père l'a décrit, et quand n=1 (ta surprise), elle aura fini de s'appeller, et le programme se terminera.

Apres pour les accolades, il n'est en effet pas nécessaire d'en mettre pour une seule ligne d'instruction, mais ca permet d'éviter des erreurs, donc c'est toi qui vois si tu veux en mettre ou pas.

Sheeps.
0
cap'tain sheeps
17 mai 2011 à 14:42
Désolé pour l'enchainement des messages, non, ton instruction printf("De la tour %d à la tour %d\n", t1, t2) ; ne se déclanchera que lors de la découverte de ta surprise.
0
apres je fais la suivante deplacer (n-1, t3, t2, t1) ; et ca donne (0,3,2,1)
Non ! car à ce moment là, n vaut 2 comme avant l'appel à deplacer(1,1,2,3)
Rien dans ton programme ne modifie la valeur de n.

Et contrairement à ce qu'écrit cap'tain sheeps , le programme ne modifie pas les valeurs des variables et ne s'arrêtera pas quand n vaudra 1.
Le programme s'appelle de manière récursive avec différentes valeurs des paramètres, mais cela ne modifie pas ses variables.
Il s'arrêtera à la fin de l'exécution du premier appel, et n vaudra 3 lors de cet arrêt, puisque cette fonction a été appelée avec n=3.
0
kimodev Messages postés 10 Date d'inscription mardi 17 mai 2011 Statut Membre Dernière intervention 18 mai 2011
17 mai 2011 à 15:57
execusez moi j'ai du mal à suivre ca avec la main franchement je n'arrive pas à trouver comment tu as fais pour arriver à ces etapes et ca me decourage vraiment à chaque fois je le refais je ne comprends pas svp aidez moi
0
cap'tain sheeps
17 mai 2011 à 16:41
Oui excuse moi je me suis lancé dans mes explications sans lire la question attentivement.
En effet, les valeur des variables ne changent pas, ce sont tes paramètres de déplacer qui vont changer.
Je vais te faire un début de chemin pour que tu comprennes:
Tu pars de ton main, et tu appelle la fonction avec :
n=3 , t1=1 , t2=3 , t3=2 .
tu rentre donc dans le else, et tu va appeller cette même fonction (une 2eme couche d'appel) avec :
n=2 , t1=1 , t2=2 , t3=3
tu rentre encore dans ton else et pareil (une 3eme couche d'appel) avec
n=1, t1=1, t2= 3, t3=2
cette fois tu rentre dans le if, ce qui affichera ton printf(), et retournera aux instructions suivantes de la 2eme couche d'appel, où les paramètres étaient (au départ) n=2 , t1=1 , t2=2 , t3=3
mais tu continue son traitement, contrairement à ce que je t'ai dis précédemment(désolé...)
donc tu fais une 3ème couche d'appel avec tes paramètre:
n=1 , t1=1 , t2=2 , t3=3
Dans cette 3eme couche, tu rentre dans le if et affiche ton printf. Tu reviens donc à ta 2ème couche avec le dernier deplacer() tout en ayant les mêmes paramètres de départs de la 2eme couche) et appel ta fonction avec:
n=1 , t1=3 , t2=2 , t3=1
tu rentres dans le if de cette 3eme couche, tu affiche donc ton printf, et tu reviendras enfin à ta 1ère couche.

Voilà continue comme ca et tu trouvera toutes les étapes de le père.
Encore une fois désolé pour mes mauvaises indications.
Bon courage.
Sheeps.
0
kimodev Messages postés 10 Date d'inscription mardi 17 mai 2011 Statut Membre Dernière intervention 18 mai 2011
17 mai 2011 à 17:01
ooooh maintenant j'ai pu comprendre cette recurcivité,franchement je vous remercie bcp vous avez pu me supporter et m'expliqué pas à pas
merci encore une fois à vous tous vous étiez vraiment collaboratifs ave moi(surtout que c ma 1ere visite)
0
cap'tain sheeps
18 mai 2011 à 09:16
Avec plaisir, n'oublie pas de signaler que ton sujet est résolu.
0
kimodev Messages postés 10 Date d'inscription mardi 17 mai 2011 Statut Membre Dernière intervention 18 mai 2011
18 mai 2011 à 21:11
en effet je me ss trompée j'ai cru que j'ai compris mais malheureusement nn ...
j'aimerai savoir si je ne vous derange pas qu'apres l'affichage u 1er printf, je retourne aux bloc du else,avec les parametres n=2 , t1=1 , t2=2 , t3=3 alors si j'ai compris j'applique la 2eme càd deplacer( 1 , t1, t2, t3) ;donc le resultat est (1,1,3,2) et j'affiche le msg du printf
apres ca je ne sais pas de quelle parametre je vais retourner est ce que avec n=2 , t1=1 , t2=2 , t3=3 (si oui alors ppk?si dans la recursivité on appelle la fonction avec les derniers parametres(1,1,3,2) ) et apres ca est ce que je saute directement à la 2eme instruction de else ou bien je refais par ordre chaque instruction de else (si oui aloors je vais tomber dans le cas de n=0)
voilà les questions qui m'embent vraiment et là ou je sens que je ss "stupide "
sl encore pour ce grand derangement et merci d'avance
0