7 réponses
mamiemando
Messages postés
33446
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
20 décembre 2024
7 812
7 août 2006 à 01:14
7 août 2006 à 01:14
Alors en fait tu es dans un cas très proche du fact2 que je t'ai proposé. En fait tu as deux variables, le noeud courant (qui correspondant à mon x), et le total calculé (ma variable res). Tu vois donc immédiatemment qu'il va falloir faire un truc dans le même genre. Ta fonction recursive (qui correspond a mon fact_rec) calculera la taille d'un sous-arbre à un noeud donné et prendra en paramètre le total calculé. La fonction faisant le calcul sera donc juste un appel à cette fonction avec res=0 et comme noeud la racine.
Comme c'est vraiment très proche et que tu n'es pas loin de la solution je te laisse chercher mais tu y es presque. Bien sûr si tu ne t'en sors pas je t'aiderai.
Ne perds pas de vue que dans ton cas la recursivité se fait sur deux "fils" le fils gauche et le fils droit mais que sinon le raisonnement est similaire.
Bonne chance
Comme c'est vraiment très proche et que tu n'es pas loin de la solution je te laisse chercher mais tu y es presque. Bien sûr si tu ne t'en sors pas je t'aiderai.
Ne perds pas de vue que dans ton cas la recursivité se fait sur deux "fils" le fils gauche et le fils droit mais que sinon le raisonnement est similaire.
Bonne chance
La récursivité (bis):
Je ne sais pas si ça peut encore servir mais bon, je me lance :
je vais essayer de vous traduire mon approche comme je le vois, en utilisant les pointeurs:
un fonction est de la forme:
fonction boucle(nœud)
début
Si {la racine est nulle} alors le résultat = 0
sinon, on fait
résultat = résultat + 1
boucle(nœud_fils)
fin
- cette fonction commence à la racine;
- elle regarde si le premier nœud existe;
- s'il n'existe pas, la fonction renvoie le résultat à 0;
- sinon, il ajoute +1 au résultat;
- et il recommence le même processus avec le nœud fils;
- s'il n'existe pas, alors le résultat est 1;
- sinon, il ajoute +1 au résultat précédent donc, le résultat = 2;
- et il recommence ainsi de suite jusqu'à un nœud_fils inexistant;
Ce qu'il faut comprendre, c'est que la première ligne de code nous dit que le résultat est nul si le nœud de l'arbre est inexistant. Or l'ordinateur comprend que la condition "résultat=0" n'est valable que pour le premier nœud ou le nœud racine. Donc, le résultat n'est pas réinitialisé quand un nœud fils existe.
La fonction continuera alors sa boucle jusqu'à ce qu'il ne trouve plus de noeud fils.
J'espère avoir été assez clair et que j'ai aidé quelqu'un à comprendre quelque chose.
Bonne prog à tous!!!
Je ne sais pas si ça peut encore servir mais bon, je me lance :
je vais essayer de vous traduire mon approche comme je le vois, en utilisant les pointeurs:
un fonction est de la forme:
fonction boucle(nœud)
début
Si {la racine est nulle} alors le résultat = 0
sinon, on fait
résultat = résultat + 1
boucle(nœud_fils)
fin
- cette fonction commence à la racine;
- elle regarde si le premier nœud existe;
- s'il n'existe pas, la fonction renvoie le résultat à 0;
- sinon, il ajoute +1 au résultat;
- et il recommence le même processus avec le nœud fils;
- s'il n'existe pas, alors le résultat est 1;
- sinon, il ajoute +1 au résultat précédent donc, le résultat = 2;
- et il recommence ainsi de suite jusqu'à un nœud_fils inexistant;
Ce qu'il faut comprendre, c'est que la première ligne de code nous dit que le résultat est nul si le nœud de l'arbre est inexistant. Or l'ordinateur comprend que la condition "résultat=0" n'est valable que pour le premier nœud ou le nœud racine. Donc, le résultat n'est pas réinitialisé quand un nœud fils existe.
La fonction continuera alors sa boucle jusqu'à ce qu'il ne trouve plus de noeud fils.
J'espère avoir été assez clair et que j'ai aidé quelqu'un à comprendre quelque chose.
Bonne prog à tous!!!
mamiemando
Messages postés
33446
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
20 décembre 2024
7 812
6 août 2006 à 22:06
6 août 2006 à 22:06
La récursivité ressemble au raisonnement par récurrence que tu as du voir en math. Sauf que dans le raisonnement par récurrence on va de n à n+1 en partant d'un rang (par exemple 0). La récursivité c'est là même chose mais dans l'autre sens. Le rang 0, où l'on s'arrête correspond à ce qu'on appelle le cas d'arrêt.
Exemple : factorielle 5! = 1*2*3*4*5
Tu constates que pour la version récursive il faut transmettre dans l'appel recursif la valeur de res (fonction fact_rec). Comme l'utilisateur ne doit pas avoir à l'initialiser à 1, on écrit une fonction fact2 qui est celle qu'il manipulera sans avoir à se soucier de la valeur à mettre pour res.
J'espère que pour toi c'est plus clair ! Dans le cas d'un arbre on est effectivement de faire des appels récursifs donc il faut réfléchir à tes cas d'arrêts (on a atteint une feulle par exemple) et parcourir chaque branche fille dans ton appel récursif.
Bonne chance
Exemple : factorielle 5! = 1*2*3*4*5
// méthode itérative : unsigned int fact(unsigned int x){ unsigned int i,res = 1; for(i=1;i<x;++i){ res *= i; // ou si tu préfères res= res * i; } } // methode recursive : cas d'arrêt 0 ou 1: unsigned int fact_rec(unsigned int x,unsigned int res){ if ( x == 0 || x == 1 ) return 1; return fact_rec(x-1,res*x); } unsigned int fact2(unsigned int x){ return fact_rec(x,1); }
Tu constates que pour la version récursive il faut transmettre dans l'appel recursif la valeur de res (fonction fact_rec). Comme l'utilisateur ne doit pas avoir à l'initialiser à 1, on écrit une fonction fact2 qui est celle qu'il manipulera sans avoir à se soucier de la valeur à mettre pour res.
J'espère que pour toi c'est plus clair ! Dans le cas d'un arbre on est effectivement de faire des appels récursifs donc il faut réfléchir à tes cas d'arrêts (on a atteint une feulle par exemple) et parcourir chaque branche fille dans ton appel récursif.
Bonne chance
bonsoir
merci beaucoup pour cette explicatiopn détaillée et claire
je vais vous expliquer en détail le probleme que g rencontré
voici une fonction en c qui calcule la taille d'un arbre binaire (c a dire le nombre de ses noeuds) selon un parcours infixé de l'arbre ,en utilisant un algorithme récursif
int taille (arbre racine)
{int nb=0;
if (racine!=NULL)
{nb=nb+taille((*racine).fg);
nb++;
nb=nb+taille((*racine).fd);
}
return(nb);}
fg est le sous arbre gauche,fd est le sous arbre droit
cette fonction s'execute normalement et donne le bon résultat mais comment ça se fait si le nb est réinitialisé a 0 pr chaque appel récursif? selon ma loqique ,moi,le résultat est 0,(ce qui prouve que je ne comprends toujours pas le principe de cette récursivité) j'espere que vous avez compris mon pti probleme
merci
merci beaucoup pour cette explicatiopn détaillée et claire
je vais vous expliquer en détail le probleme que g rencontré
voici une fonction en c qui calcule la taille d'un arbre binaire (c a dire le nombre de ses noeuds) selon un parcours infixé de l'arbre ,en utilisant un algorithme récursif
int taille (arbre racine)
{int nb=0;
if (racine!=NULL)
{nb=nb+taille((*racine).fg);
nb++;
nb=nb+taille((*racine).fd);
}
return(nb);}
fg est le sous arbre gauche,fd est le sous arbre droit
cette fonction s'execute normalement et donne le bon résultat mais comment ça se fait si le nb est réinitialisé a 0 pr chaque appel récursif? selon ma loqique ,moi,le résultat est 0,(ce qui prouve que je ne comprends toujours pas le principe de cette récursivité) j'espere que vous avez compris mon pti probleme
merci
Darshu
Messages postés
303
Date d'inscription
lundi 30 janvier 2006
Statut
Membre
Dernière intervention
3 avril 2008
64
7 août 2006 à 09:20
7 août 2006 à 09:20
Comme l'a dit mamiemambo, c'est vraiment très similaire.
Pour le nb =0; c'est assez simple : quand tu rappelles la fonction, tu va ajouter le résultat que te retournes le deuxième appel au résultat du premier ... En effet, il y a nb = nb + taille() donc on incrémente nb du nombre taille() qui lui même va faire appel à taille(), et ce tant que racine ne vaut pas NULL. A ce moment la, on ne rentre pas dans le if, donc on renvoie 0. L'appel précédent, pour lequel racine n'est pas NULL, rentre dans le if, incrémente nb (qui vaut donc 1 pour cet appel) et renvoie nb + taille, c'est-à-dire 1+0, donc 1. L'appel encore d'avant va récupérer nb + taille, donc 1 +1 =2. L'appel encore d'avant va récupérer nb + taille, soit 1 + 2 ... Et ainsi de suite jusqu'à remonter finalement au tout premier appel de la fonction.
Bien sur, la je ne l'ai fait que pour une liste chaînée et pas un arbre binaire, mais suffit d'appliquer le même raisonnement à chaque branche de l'arbre ...
Pour le nb =0; c'est assez simple : quand tu rappelles la fonction, tu va ajouter le résultat que te retournes le deuxième appel au résultat du premier ... En effet, il y a nb = nb + taille() donc on incrémente nb du nombre taille() qui lui même va faire appel à taille(), et ce tant que racine ne vaut pas NULL. A ce moment la, on ne rentre pas dans le if, donc on renvoie 0. L'appel précédent, pour lequel racine n'est pas NULL, rentre dans le if, incrémente nb (qui vaut donc 1 pour cet appel) et renvoie nb + taille, c'est-à-dire 1+0, donc 1. L'appel encore d'avant va récupérer nb + taille, donc 1 +1 =2. L'appel encore d'avant va récupérer nb + taille, soit 1 + 2 ... Et ainsi de suite jusqu'à remonter finalement au tout premier appel de la fonction.
Bien sur, la je ne l'ai fait que pour une liste chaînée et pas un arbre binaire, mais suffit d'appliquer le même raisonnement à chaque branche de l'arbre ...
slt , j'ai le meme probleme , je trouve pas de koi apprendre cette recursivité, mais dernierement g téléchargé des fichiers pdf qui pourraient t'interesser, si tu es tjrs interssée : voici certains liens , sinn laisse ton email je te les enverrai.. bonne chance
http://www.math.u-psud.fr/~lichnew/spipE/rubrique.php3?id_rubrique=52
http://www.math.u-psud.fr/~lichnew/spipE/rubrique.php3?id_rubrique=52
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Darshu
Messages postés
303
Date d'inscription
lundi 30 janvier 2006
Statut
Membre
Dernière intervention
3 avril 2008
64
6 août 2006 à 22:14
6 août 2006 à 22:14
Hum, la récursivité n'est pas forcément facile à comprendre au début, mais dès que t'a eu le déclic tout marche bien.
Le principe c'est que la fonction s'appelle elle même, ce qui risque de générer des appels infinis ! Il faut donc bien aire attention à mettre des conditions d'arrêt, et à faire évoluer les variables pour qu'elles se mettent bien à jour.
Après te parler de la récursivité en général comme ça, c'est pas facile ... Pour les arbres binaires, ça peut servir à faire une recherche sans savoir combien d'enregistrement il y a, jusqu'à trouver le bon si on a un pointeur dessus par exemple ...
Voila un exemple de fonction récursive toute bête qui calcule la somme des n premiers entiers :
int somme(int n)
{
int s=0;
if (n > 1)
return s += somme(n-1);
else
return 1;
}
En espérant que ça peut t'aider à comprendre ce que c'est ...
Le principe c'est que la fonction s'appelle elle même, ce qui risque de générer des appels infinis ! Il faut donc bien aire attention à mettre des conditions d'arrêt, et à faire évoluer les variables pour qu'elles se mettent bien à jour.
Après te parler de la récursivité en général comme ça, c'est pas facile ... Pour les arbres binaires, ça peut servir à faire une recherche sans savoir combien d'enregistrement il y a, jusqu'à trouver le bon si on a un pointeur dessus par exemple ...
Voila un exemple de fonction récursive toute bête qui calcule la somme des n premiers entiers :
int somme(int n)
{
int s=0;
if (n > 1)
return s += somme(n-1);
else
return 1;
}
En espérant que ça peut t'aider à comprendre ce que c'est ...
bonjour
merci de vous interesser a mon probleme, et bien g pensé a voir sur google, mais ça m'a pas beaucoup aidé, pour comprendre g essayé de faire le déroulement de ces fonctions récursives sur un papier en utilisant les piles , mais je m'embrouille tout le temps, je ne sais pas pourquoi je suis la seule a trouver ça si compliqué, en plus ne soyez pas surpris, je ne comprend toujours pas l'histoire de ce nb initialisé a zéro.
merci
merci de vous interesser a mon probleme, et bien g pensé a voir sur google, mais ça m'a pas beaucoup aidé, pour comprendre g essayé de faire le déroulement de ces fonctions récursives sur un papier en utilisant les piles , mais je m'embrouille tout le temps, je ne sais pas pourquoi je suis la seule a trouver ça si compliqué, en plus ne soyez pas surpris, je ne comprend toujours pas l'histoire de ce nb initialisé a zéro.
merci
mamiemando
Messages postés
33446
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
20 décembre 2024
7 812
8 août 2006 à 19:04
8 août 2006 à 19:04
Je n'ai pas testé mais c'est quelque chose dans l'idée
Bonne chance
typedef struct noeud{ struct noeud * fg; // fils gauche struct noeud * fd; // fils droit } noeud; typedef struct arbre{ struct noeud * root; // la racine } arbre; // on passe n en int * afin que n soit modifié par les appels recursifs // cf cours sur les pointeurs void card_rec(noeud * a,unsigned int * n){ if (a->fg){ // si j'ai un fils gauche // j'ajoute à n le nombre de fils comptés à partir de fg card_rec(a->fg,n); } if (a->fg){ // si j'ai un fils droit // j'ajoute à n le nombre de fils comptés à partir de fd card_rec(a->fd,n); } ++ *n; // j'ajoute le noeud courant } unsigned int card(arbre * a){ // actuellement j'ai compté 0 noeuds, et je pars de la racine unsigned int res=0; card_rec(a->root,&res); return res; }
Bonne chance