Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2861 connectés 

 


Dernière réponse
Sujet : les arbres binaires
swich l'hammeral, ok, je le note.
j'espere qu'il est en francais...
merci bien
 :bounce:

Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
swich l'hammeral, ok, je le note.
j'espere qu'il est en francais...
merci bien
 :bounce:
mystereetbouledegomme L'Hammeral est un "bon" bouquin d'algorithmique. Tu y trouveras tout ce que tu veux sur les arbres et le rebalancement(reequilabrage si tu veux). Tu as pense a l'implementation d'un arbre dans un vecteur?
zeltron Pour les arbres binaires équilibrés c'est un peu plus compliqué je vais juste te donner quelque indications car je n'ai pas le temps et tu pourras réfléchir un peu dessus :
 
il faut que tu change ta structure d'arbre en  
{arbre *gauche; arbre *droit; arbre *pere; int coefficient_de_desequilibre} où coefficient_de_desequilibre est la différence entre la hauteur du fils droit et celle du fils gauche par exemple pour un arbre équilibré (en hauteur) ca vaudra donc -1 0 ou 1
 
Il te faudra utiliser quatre petites fonctions élémentaires:
 
arbre gauche_gauche(arbre a) {
if (a != NULL)
   {arbre temp = a-> droit;
    a->droit = temp->gauche;
    temp->gauche=a;
    a=temp;
  }
  return a;
}
 
Sur le meme principe tu construits la fonction droit_droit.
 
Ensuite;
 
arbre gauche_droit(arbre a)
{a->gauche = gauche_gauche(a->gauche);
  return droit_droit(a);
}
 
Sur le même principe tu construits la fonction droit_gauche.
 
Il te reste plus qu'à insérer tes éléments en utilisant ton coefficient de désiquilibre et tes quattre petites fonctions.
Je te conseille sérieusement de faire des schémas pour comprendre ce que font tes 4 fonctions et comment les utiliser. (Après à toi de mater ton cours de Scheme pour implémenter l'algo)

 

[edit]--Message édité par zeltron--[/edit]

swich ok merci bien zetes gentil les gars mais bon, mon pb c'est en scheme...
mais bon merci qd meme ca m'aide.
comment peut on construire un arbre binaire equilibre???
BifaceMcLeOD legreg> Le problème du C, c'est que ce genre de boucle n'est pas super lisible, parce qu'on ne voit pas très bien le ou les endroits où on quitte la boucle. Dans ces cas-là, j'utilise 2 macros toutes simples qui éclaircissent pas mal le code (à mon avis) :
 
    #define forever() for( ; ; )
    #define EXIT_WHEN(condition) if (condition) break
 
En les utilisant, le code ci-dessus devient :
 
ajoute(insere, ref racine) {
 if (racine == null) {
  racine = nouveau noeud (insere, null, null);
 } else {
  courant = racine;
  forever() {
   if (courant->valeur > insere) {
     if (courant->filsgauche == null) {
       courant->filsgauche = nouveau noeud(insere, null, null);
 
       EXIT_WHEN(true);
     } else {
       courant = courant->filsgauche;
     }
   } else {
     if (courant->filsdroit == null) {
       courant->filsdroit = nouveau noeud(insere, null, null);
 
       EXIT_WHEN(true);
     } else {
       courant = courant->filsdroit;
     }
   }
  }
 }
}
 
Sinon, juste pour le plaisir de critiquer ;) , pour obtenir un code le plus lisible possible, il vaut mieux limiter l'imbrication du code, et factoriser au maximum le code. Je proposerai donc la réécriture du code de legreg suivante :
 
ajoute(insere, ref racine) {
  if (racine == null) {
    racine = nouveau noeud (insere, null, null);
    return;
  }
 
  courant = racine;
  var pfils_courant;   // On déclare une variable de type "pointeur sur le type de courant".
 
  forever() {
    if (courant->valeur > insere) {
      pfils_courant = &courant->filsgauche;
    }
    else {
      pfils_courant = &courant->filsdroit;
    }
 
    if (*pfils_courant == null) {
      *pfils_courant = nouveau noeud(insere, null, null);
 
      EXIT_WHEN(true);
    }
    else {
      courant = *pfils_courant;
    }
  }
}

 

[edit]--Message édité par BifaceMcLeOD--[/edit]

LeGreg Une methode toujours efficace c'est de passer par des boucles conditionnelles, ce qui est efficace quel que soit
le compilateur utilise:
 
ajoute(insere, ref racine) {
 if (racine == null) {
  racine = nouveau noeud (insere, null, null);
 } else {
  courant = racine;
  while (true) {
   if (courant->valeur > insere) {
     if (courant->filsgauche == null) {
       courant->filsgauche = nouveau noeud(insere, null, null);
       break;
     } else {
       courant = courant->filsgauche;
     }
   } else {
     if (courant->filsdroit == null) {
       courant->filsdroit = nouveau noeud(insere, null, null);
       break;
     } else {
       courant = courant->filsdroit;
     }
   }
  }
 }
}
Legreg
LeGreg exemple recursif non terminal:
compter (n) {
  if (n>0)
  return compter(n-1)+1;
  else
  return 0;
}
 
Le meme en recursif terminal:
compter (n, res) {
  if (n>0)
  return compter(n-1,res+1);
  else
  return res;
}
 
et il faut l'initialiser par un compter(n,0);
 
Tu remarqueras que dans le premier cas, il est
necessaire de memoriser le contexte d'appel de compter()
puisqu'au retour de la fonction il faudra encore effectuer l'operation +1 sur la valeur de retour.
Dans le deuxime cas par contre, pas besoin de stocker ce contexte d'appel.
en effectuant le calcul pour n avec la premiere methode,
tu mets n procedures en attente, tandis qu'avec la deuxieme, chaque procedure passe le bebe a la suivante et ne doit rien attendre.
 
A+
LEGREG
swich ah :(
ben c'est pas cool ca car je comprend pas..., pourtant la recursivite, j'ai pas de pb..
verdoux L'algo donné est en récursivité terminale.
swich hein ???
verdoux Elle est pas terminale mais récursivité ?
swich le principe c'est bon j'ai compris, mais c'est pour ce qui est de la construction de l'arbre...
verdoux a resume l'algo en recursif normale, mais bon comme je travaille avec des grosses liste... la recursivite terminale, je crois que c'est ce qu'il y'a de mieux.et c la que ca plante.
j'y arrive pas.
donc c'est ce que je demandais, une explication pour la recursivite terminale.
pff ca fait 1semaine que je suis sur ce pb ca commence a me peter les c@@@@@@s....
verdoux Si les noeud de ton arbres ont la structure suivante:
- valeur v
- référence/pointeur sur noeud gauche rng
- référence/pointeur sur noeud gauche rnp
 
alors tu peux utiliser la procédure suivante:
ajout( nouvelle valeur nv, référence sur un noeud rn):
 si (nv > rn-> v)
 alors
  si (rn->rnd vide)
  alors
   créer une feuille avec la valeur nv et affecter à rn->rnd une réference vers cette feuille
  sinon
   ajoute(nv, rn->rnd)
 sinon
 .... // la même chose avec le noeud fils gauche
swich ben le principe, c'est bon.
il me faudrait l'algo (pour le construire en normal, c'est bon, mais c'est pour le construire en recursivite terminale, et la j'ai du mal...j'y arrive pas.
 
si qq'un connait, comment faire pour eviteer l'erreur : error : could not grow, sous emacs ???
gizmo watouwatou >> très douteux comme humour :sweat:  
 
Sinon, ddr555 a bien expliqué le bazard, mar swich, tu ne nous as toujours pas expliquer ce que tu veux EXACTEMENT, s'il s'agit du principe, de l'implémentation, de l'algo général, du rebalancement de l'arbre...
ddr555 bon pour résumer, je dirai que c'est uns structure de données destinée à trier les éléments pour accélérer l'insertion et la recherche de données.
dans le cas des binaires, il y a au plus deux fils, et on détermine en fonction d'un ordre de tri le placement dans l'arbre ( généralement, c'est l'ordre > ou < qui est utilisé ).
par exemple dans le cas d'un arbre stockant des entiers, on détermine la place dans l'arbre en testant les valeurs dans le noeud courant, si c'est supérieur on cherche dans l'arbre droit, si c'est supérieur on cherche dans l'arbre gauche.
 
donc cela doit donner pour insérer un élément, on cherche d'abord dans la racine. si y'a rien dans la racine, alors on crée l'élément dans la racine.
sinon, on teste avec la valeur et si la valeur est supérieure à la valeur de la racine, on regarde si il y a quelquechose dans le fils droit. si y'a rien on crée la valeur dans le fils droit, sinon on reprend le cas de figure racine.
si c'est inférieur, on fait le même test que juste au dessus.
ceci est un algorithme récursif qui te permettra d'insérer des valeurs dans un arbre binaire de recherche. pour rechercher une valeur, c'est exactement le même algorithme, sauf qu'on insère rien. pour afficher la liste, on affiche d'abord le fils gauche, puis la racine, puis le fils droit. lorsqu'on tombe sur une feuille ( c'est à dire un noeud sans fils ) on affiche la valeur et basta.
pour supprimer un élément, c'est un peu plus compliqué, mais si tu as déjà compris le principe de l'arbre binaire, tu trouveras comment supprimer.
principal inconvénient des arbres binaires de recherche : tu n'es pas sur d'avoir un arbre bien équilibré ( comme celui que tu as fourni en exemple ). par contre là, pour rééquilibrer l'arbre, c'est nettement plus compliqué.
si tu n'as rien compris à ce que je viens de dire, ou que tu ne sais pas comment fonctionnent les pointeurs pour faire un arbre binaire de recherche, n'hésites pas à reposer d'autres questions.
wouatouwouatou ben... voila, c kom dans les camps avec ls juifs ...
 
Les femmes a gauche et les hommes a droite :D
swich vi c'est ca.
mais bon ca je le savais....
BlackLotus Alors un arbre binaire en programmation fonctionnel c'est
 
(la notation)
(/G,r,D\)  
 
avec G partie Gauche, r racine et D partie Droite
 
G et D sont considéré comme racines de sous-arbres binaires
En partant d'une racine, il ne peux y avoir que deux branches dans un arbre binaire.
swich vi arbre binaire de recherche sur des chaine de caractere.
ex :
 
  a
   \
   an
     \
      annuel
     /
    anne
 
etc

 

[edit]--Message édité par swich--[/edit]

nabab Tu veux dire binaire ?
Arbre binaire de recherche ?
gizmo précise ce que tu veux...
swich qq'un pourrait m'expliquer comment ca marche...
parce que la je capte rien du tout...

 

[edit]--Message édité par swich--[/edit]


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)