Arbre et recursivite : petit probleme a l'execution

Arbre et recursivite : petit probleme a l'execution - C - Programmation

Marsh Posté le 18-11-2005 à 22:38:49    

Bonsoir,
 
Ci-dessous, le code qui me pose un souci.
Dans le main je cree un chtit arbre avec juste 2 feuilles.
Lorsque j'execute parcours(a) on voit bien le deroulement de l'arbre donc pas de probleme de ce cote :
   racine qui contient 1  
   pointe sur fils gauche qui contient 2
   pointe sur fils droit qui contient 3
Ensuite j'ai une fonction chercheFeuille qui va chercher une feuille de la valeur passee en parametre sur l'arbre passe en parametre.
Pour controler, jai mis un printf dans la fonction pour verifier si le contenu est le bon...
Lorsque je demande chercheFeuille(a,1), le programme me renvoie bien 1 que j'affiche aussi bien dans le printf avant le return de la fonction que dans le main apres l'appel de la fonction.
Par contre si je demande chercheFeuille(a,2), le printf de la fonction elle-meme me dit que j'ai bien la bonne feuille mais lorsaue j'affiche son contenu une fois de retour dans le main, j'ai un truc de ce genre : -1073743462
Pourtant ce qui m'est renvoye est bien du type Arbre puisque je n'ai pas d'erreur a la compil. Alors d'ou viens cette valeur bizarre ???
Qui peut au moins me mettre sur la voie pour depatouiller ca ?
merci !!!
 
EDIT: avec le code, c'est mieux... :lol:  
 
 
# include <stdio.h>
# include <stdlib.h>
 
typedef struct _arbre {
  int contenu ;
  struct _arbre *gauche ;
  struct _arbre *droit ;
} Arbre ;
 
void parcours( Arbre *a ) {
  if ( a != NULL ) {
    printf("%d\n",a->contenu) ;
    parcours (a->gauche) ;
    parcours (a->droit) ;
  }
}
 
Arbre * chercheFeuille ( Arbre *a , int n ) {
  if ( a->contenu == n ){
    printf ("contenu=%d\n",a->contenu);  
    return a ;
  }
    if (a->gauche!=NULL && a->droit!=NULL) {
      chercheFeuille ( a->gauche,n ) ;
      chercheFeuille ( a->droit,n ) ;
  }
}
 
main () {
  Arbre *a ;
  Arbre *f1 ;
  Arbre *f2 ;
  a=(Arbre *) malloc (sizeof(Arbre)) ;
  f1=(Arbre *) malloc (sizeof(Arbre)) ;
  f2=(Arbre *) malloc (sizeof(Arbre)) ;
  a->contenu = 1 ;
  f1->contenu = 2 ;
  f2->contenu = 3 ;
  a->gauche = f1 ;
  a->droit = f2 ;
  f1->gauche = NULL ;
  f1->droit = NULL ;
  f2->gauche = NULL ;
  f2->droit = NULL ;
 
  parcours(a) ;
 
  Arbre *nf ;
  nf=(Arbre *) malloc (sizeof(Arbre)) ;
 
  nf=chercheFeuille(a,2) ;
  printf("vous cherchiez %d\n",(nf->contenu));
}


Message édité par fabrice91 le 18-11-2005 à 22:52:37
Reply

Marsh Posté le 18-11-2005 à 22:38:49   

Reply

Marsh Posté le 18-11-2005 à 23:13:38    

Code :
  1. Arbre * chercheFeuille ( Arbre *a , int n ) {
  2.   if ( a->contenu == n ){
  3.     printf ("contenu=%d\n",a->contenu); 
  4.     return a ;
  5.   }
  6.     if (a->gauche!=NULL && a->droit!=NULL) {
  7.       chercheFeuille ( a->gauche,n ) ;
  8.       chercheFeuille ( a->droit,n ) ;
  9.   }
  10. }


 
l'erreur est la, et super visible

Reply

Marsh Posté le 18-11-2005 à 23:38:15    

:??:  :??:  :??:  
oui je l'ai deja cherche la un bon moment mais bon je vois pas...

Reply

Marsh Posté le 18-11-2005 à 23:38:58    

si a->contenu n'est pas egal a n, que va renvoyer ta fonction ?
 
(et je crois que tu compilo te previens, d'ailleurs [:el g])

Reply

Marsh Posté le 18-11-2005 à 23:40:45    

Citation :

Pourtant ce qui m'est renvoye est bien du type Arbre puisque je n'ai pas d'erreur a la compil.


Code :
  1. Arbre * chercheFeuille ( Arbre *a , int n ) {
  2.   if ( a->contenu == n ){
  3.     printf ("contenu=%d\n",a->contenu); 
  4.     return a ;
  5.   }
  6.     if (a->gauche!=NULL && a->droit!=NULL) {
  7.       chercheFeuille ( a->gauche,n ) ;
  8.       chercheFeuille ( a->droit,n ) ;
  9.   }
  10. }


Tu devrais régler correctement ton compilo, tu devrais au moins avoir un warning.

Reply

Marsh Posté le 19-11-2005 à 00:40:44    

chrisbk a écrit :

si a->contenu n'est pas egal a n, que va renvoyer ta fonction ?
 
(et je crois que tu compilo te previens, d'ailleurs [:el g])


aucun message du compilo...
bah je n'ai pas le cas a->contenu n'est pas egal a n puisque je passe explicitement un n qui est contenu dans mon arbre...2 en l'occurence...et le printf de la fonction me confirme bien qu'il voit bien que a->contenu est bien egal a 2 donc lorsque je return "a" je devrais retrouver la meme valeur dans contenu !!!
bon ben merci pour l'aide, j'ai trop mal au crane, la...je verrais ca demain mais ca fait plusieurs jours que je coince sur ce satane truc... :fou:

Reply

Marsh Posté le 19-11-2005 à 00:42:49    

fabrice91 a écrit :

aucun message du compilo...
bah je n'ai pas le cas a->contenu n'est pas egal a n puisque je passe explicitement un n qui est contenu dans mon arbre...2 en l'occurence...et le printf de la fonction me confirme bien qu'il voit bien que a->contenu est bien egal a 2 donc lorsque je return "a" je devrais retrouver la meme valeur dans contenu !!!
bon ben merci pour l'aide, j'ai trop mal au crane, la...je verrais ca demain mais ca fait plusieurs jours que je coince sur ce satane truc... :fou:


 
bon déroulons le cas que j'essaye de te faire voir
 
je cherche 5, et a->contenu = 2;
 
est ce que a->contenu est egal a 5 ?
non
lance recherche sur feuille gauche
lance recherche sur feuille droite
 
return. <=== mais LA, a cet endroit LA, je retourne QUOI ?
 

Reply

Marsh Posté le 19-11-2005 à 01:00:26    

chrisbk a écrit :


return. <=== mais LA, a cet endroit LA, je retourne QUOI ?


euh bah rien puisque justement je veux pas 5, je veux 2...
donc je refait la fonction avec l'arbre gauche puis avec l'arbre droit jusqu'a avoir mon contenu=2...

Reply

Marsh Posté le 19-11-2005 à 01:07:26    

bon je sens qu'on va pas y arriver
donc la réponse est :
 

Code :
  1. Arbre * chercheFeuille ( Arbre *a , int n ) {
  2.   if ( a->contenu == n ){
  3.     printf ("contenu=%d\n",a->contenu); 
  4.     return a ;
  5.   }
  6.     if (a->gauche!=NULL)
  7.     {
  8.       Arbre * tmp = chercheFeuille ( a->gauche,n ) ;
  9.       if (tmp != NULL) return tmp;
  10.     }
  11.     if (a->droit!=NULL)
  12.     {
  13.       Arbre * tmp = chercheFeuille ( a->droit,n ) ;
  14.       if (tmp != NULL) return tmp;
  15.     }
  16.   }
  17.   return NULL;
  18. }


 
tu vois ?

Message cité 1 fois
Message édité par chrisbk le 19-11-2005 à 01:07:38
Reply

Marsh Posté le 19-11-2005 à 01:23:24    

chrisbk a écrit :

bon je sens qu'on va pas y arriver
donc la réponse est :
 

Code :
  1. Arbre * chercheFeuille ( Arbre *a , int n ) {
  2.   if ( a->contenu == n ){
  3.     printf ("contenu=%d\n",a->contenu); 
  4.     return a ;
  5.   }
  6.     if (a->gauche!=NULL)
  7.     {
  8.       Arbre * tmp = chercheFeuille ( a->gauche,n ) ;
  9.       if (tmp != NULL) return tmp;
  10.     }
  11.     if (a->droit!=NULL)
  12.     {
  13.       Arbre * tmp = chercheFeuille ( a->droit,n ) ;
  14.       if (tmp != NULL) return tmp;
  15.     }
  16.   }
  17.   return NULL;
  18. }


 
tu vois ?


 
 :cry:  
ca me desespere...
je ne comprends pas a quoi sert le return tmp...il m'interesse pas puisque a priori il est pas dans le cas de l'egalite entre la valeur que je cherche et celle que je trouve...
pourquoi cette seule condition ne suffit pas ???
 
if ( a->contenu == n ){
    printf ("contenu=%d\n",a->contenu);    
    return a ;
  }
 
ca me paraissait tellement evident...

Reply

Marsh Posté le 19-11-2005 à 01:23:24   

Reply

Marsh Posté le 19-11-2005 à 01:24:40    

es tu sur d'avoir compris le principe de la recursivité ?

Reply

Marsh Posté le 19-11-2005 à 01:35:26    

chrisbk a écrit :

es tu sur d'avoir compris le principe de la recursivité ?


bof...
sur des trucs simples, vi j'ai compris...je l'ai compris pour Fibonacci ou bien pour compter les noeuds de mon arbre...
je vois comment ca marche mais je vois pas comment l'implementer...
je comprends le principe mais pour coder une solution la je suis paume...
apres 4 ans de programmation Perl exclusivement en iteratif, le passage au recursif est pas evident...et je trouve rien nulle part qui l'explique correctement...j'ai l'impression que c'est marche ou creve...tu comprends, tant mieux, tu comprends pas, ben accroche toi...
Enfin bref...merci beaucoup pour le coup de main meme si finalement je suis pas plus avance, un aspegic et au lit... :(

Reply

Marsh Posté le 19-11-2005 à 01:43:22    

bin depuis le temps que j'en fais j'ai du mal a voir le pb en fait
 
bon, on va prendre un exemple con
 

Code :
  1. int a()
  2. {
  3. return 2;
  4. }
  5. int b()
  6. {
  7.    a();
  8. }
  9. main()
  10. {
  11. int c  =b();
  12. }


 
bon, donc la si j'appelle b(), je vais avoir un resultat indéfini dans c
 
main appelle b
b appelle a
a renvoie 2
mais, la b ne renvoi pas 2 ! il ne renvoie rien du tout, que dalle, vu qu'on lui dit pas quoi retourner
donc dans c on aura un truc, on sait pas quoi, ca serait ptet 2 mais ca le sera ptet pas
 
 
pour ta recursion c'est pareil
 
main appelle chercheArbre
chercheArbre appelle chercheArbre
chercheArbre appelle chercheArbre
chercheArbre retourne <unNoeud>
 
 
<UnNoeud> ne va pas retourner jusqu'a main par l'operation du saint esprit, il faut qu'il "traverse" toute les fonctions appelé jusqu'a main, meme si la meme fonction a été appelée plusieurs fois
 
 

Reply

Marsh Posté le 19-11-2005 à 12:34:46    

fabrice91 a écrit :

bof...
sur des trucs simples, vi j'ai compris...je l'ai compris pour Fibonacci ou bien pour compter les noeuds de mon arbre...
je vois comment ca marche mais je vois pas comment l'implementer...
je comprends le principe mais pour coder une solution la je suis paume...
apres 4 ans de programmation Perl exclusivement en iteratif, le passage au recursif est pas evident...et je trouve rien nulle part qui l'explique correctement...j'ai l'impression que c'est marche ou creve...tu comprends, tant mieux, tu comprends pas, ben accroche toi...
Enfin bref...merci beaucoup pour le coup de main meme si finalement je suis pas plus avance, un aspegic et au lit... :(


hé ho on arrête de dire du mal de Perl, hein :o
tu peux très bien faire beaucoup de récursivité en Perl, notamment quand tu commences à toucher aux hash et aux listes (chose courante en perl)

Reply

Marsh Posté le 20-11-2005 à 14:12:25    

fabrice91 a écrit :

:cry:  
ca me desespere...
je ne comprends pas a quoi sert le return tmp...il m'interesse pas puisque a priori il est pas dans le cas de l'egalite entre la valeur que je cherche et celle que je trouve...
pourquoi cette seule condition ne suffit pas ???
 
if ( a->contenu == n ){
    printf ("contenu=%d\n",a->contenu);    
    return a ;
  }
 
ca me paraissait tellement evident...


Je vais tenter de t'expliquer autrement...
Tu as un arbre à 3 feuilles, qui contient "3, 5 à gauche et 2 à droite"
Tu appelles ta fonction (on va dire que son appel se situe au niveau 1) => celle-ci compare la première feuille "3" avec "5" => pas bon
La fonction se met en attente, et s'appelle elle-même (au niveau 2). Là, elle trouve que la feuille "5" correspond au nombre attendu "5" et renvoie donc l'adresse de la feuille à la fonction appelante, c'est à dire la fonction de niveau "1".
A ce moment là, la fonction de niveau "1" qui récupère l'adresse recherchée doit elle-aussi la renvoyer à la fonction "main" car c'est cette fonction qui en a besoin.
Tu suis ???


Message édité par Sve@r le 26-11-2005 à 14:04:06

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 21-11-2005 à 19:21:43    

couak a écrit :

hé ho on arrête de dire du mal de Perl, hein :o
tu peux très bien faire beaucoup de récursivité en Perl, notamment quand tu commences à toucher aux hash et aux listes (chose courante en perl)


Houla j'ai jamais dit du mal de Perl !!!  :ouch:  
j'ai dit "apres 4 ans de Perl en iteratif" parce que c'est comme ca que je programmais, parce que je ne connaissais pas le fonctionnement recursif...Là j'ai des cours de C et on voit le recursif donc c'est pour cela que je pose mes questions sur le C...je me doute bien que Perl sait faire du recursif...;-)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed