Afficher un arbre

Résolu
sangoku12 Messages postés 39 Statut Membre -  
sangoku12 Messages postés 39 Statut Membre -
Bonjour,

je voudrais savoir comment afficher un arbre binaire "sous la forme d'un arbre"
exemple:
******* + ******************
*** - ******* 9
* 5 ** 6 *********************

2 réponses

  1. KX Messages postés 19031 Statut Modérateur 3 020
     
    Ça va fortement dépendre de ce que tu as afficher.
    Cas simple : en console, chaque feuille/noeud est représenté par 1 caractère.

    Il te faut tout d'abord calculer la hauteur de l'arbre : h
    Du coup tu sais déjà quelle sera la ligne h, elle sera composée de 2^h caractères chacun séparés par 1 espace. De même la première ligne sera composée de 1 caractère "séparé" par 2^h espaces. Il suffit donc pour toutes les lignes k d'afficher les 2^k noeuds chacun espacés de 2^(h-k) espaces et ça devrait être à peu près bon (à quelques +/- 1 près)
    0
    1. sangoku12 Messages postés 39 Statut Membre
       
      théoriquement c'est compréhensible et logique mais je trouve des difficultés à implémenter ça!
      si c'est possible pouvez-vous me fournir l'algorithme correspondant? merci d'avance
      0
    2. KX Messages postés 19031 Statut Modérateur 3 020
       
      L'algo c'est ce que je t'ai expliqué, si c'est l'implémentation que tu veux il va falloir définir quel langage tu utilises. Mais également dire quelles genre de données tu manipules (ta structure d'arbre binaire, les données aux noeuds...) là j'ai expliqué le cas "simple" où chaque noeud est représenté par un unique caractère mais c'est rarement le cas en général et ça va tout décaler !
      0
    3. sangoku12 Messages postés 39 Statut Membre
       
      justement les noeuds de mon arbre sont soit des opérateurs soit des entiers introduits par l'utilisateur donc il peuvent être composés de plus qu'un seul chiffre
      0
    4. KX Messages postés 19031 Statut Modérateur 3 020
       
      Les entiers aussi n'ont qu'un seul chiffre ?
      Et quel est ta structure d'arbre (ton langage de programmation, ton type arbre...)
      0
    5. sangoku12 Messages postés 39 Statut Membre
       
      non il peuvent avoir plus qu'un chiffre
      j'utilise le langage C
      voici la définition des noeuds
      typedef float feuille;

      typedef struct s_noeud
      {char op_c;
      struct s_comp*filsg;
      struct s_comp*filsd;
      }noeud;

      typedef struct s_comp
      {int arite;
      union {noeud n;
      feuille f;
      }val;
      }composante;
      0
  2. KX Messages postés 19031 Statut Modérateur 3 020
     
    Je n'ai pas tout fait, j'ai voulu faire quelque chose d'assez général de sorte que ça puisse être utilisé dans n'importe quel arbre binaire, j'ai donc fait "uniquement" de la manipulation de char*

    Il te reste donc à utiliser mon code pour l'adapter à ta structure d'arbre, en faisant récursivement des créations de blocs pour les opérateurs et les opérandes ainsi que des fusions de blocs pour l'arbre et ses sous-arbres.

    Regarde bien le main qui affiche ((1.23+4.5)*(-(6.7/8.9))) pour voir comment utiliser mes méthodes, je pense que tu verras tout de suite la récursivité ;-)

    #include "stdio.h"
    #include "stdlib.h"
    #include "string.h"
    
    typedef struct s_
    {
    	size_t x,y;
    	char** tab; // tab[y][x]
    } bloc;
    
    void allouer(bloc &b,const size_t x,const size_t y)
    {
    	b.x = x;
    	b.y = y;
    
    	b.tab = (char**) malloc(y*sizeof(char*));
    
    	size_t j;
    	for (j=0; j<b.y; j++)
    		b.tab[j]= (char*) malloc(x*sizeof(char));
    }
    
    void liberer(bloc &b)
    {
    	size_t j;
    	for (j=0; j<b.y; j++)
    		free(b.tab[j]);
    
    	free(b.tab);
    }
    
    void creer(bloc &b, const char* str)
    {
    	size_t i,n=strlen(str);
    	allouer(b,n,1);
    	for (i=0; i<n; i++)
    		b.tab[0][i]=str[i];
    }
    
    void afficher(const bloc& b)
    {
    	size_t i,j;
    	for (j=0; j<b.y; j++)
    	{
    		for (i=0; i<b.x; i++)
    			printf("%c",b.tab[j][i]);
    		printf("\n");
    	}
    	printf("\n");
    }
    
    // Fusion des petits blocs en un gros bloc
    // r : bloc resultat (alloué par la fonction)
    // h : bloc en haut centré (désalloué par la fonction)
    // b : bloc en bas  centré (désalloué par la fonction)
    void fusionner(bloc &r, bloc &h, bloc &b, const char blanc=' ')
    {
    	size_t
    		i,x1,x2,x3,x4,x5,
    		j,y1=h.y,y2=y1+b.y;
    	
    	if (h.x<b.x)
    	{
    		x1=(b.x-h.x)/2;
    		x2=x1+h.x;
    		x3=0;
    		x4=b.x;
    		x5=x4;
    	}
    	else
    	{
    		x1=0;
    		x2=h.x;
    		x3=(h.x-b.x)/2;
    		x4=x3+b.x;
    		x5=x2;
    	}
    
    	allouer(r,x5,y2);
    
    	//----
    
    	for (j=0; j<y1; j++)
    	{
    		for (i=0; i<x1; i++)
    			r.tab[j][i]=blanc;
    		for (i=x1; i<x2; i++)
    			r.tab[j][i]=h.tab[j][i-x1];
    		for (i=x2; i<x5; i++)
    			r.tab[j][i]=blanc;
    	}
    
    	for (j=y1; j<y2; j++)
    	{
    		for (i=0; i<x3; i++)
    			r.tab[j][i]=blanc;
    		for (i=x3; i<x4; i++)
    			r.tab[j][i]=b.tab[j-y1][i-x3];
    		for (i=x4; i<x5; i++)
    			r.tab[j][i]=blanc;
    	}
    
    	//----
    
    	liberer(h);
    	liberer(b);
    }
    
    // Fusion des petits blocs en un gros bloc
    // r : bloc resultat (alloué par la fonction)
    // h : bloc en haut centré  (désalloué par la fonction)
    // g : bloc en bas à gauche (désalloué par la fonction)
    // d : bloc en bas à droite (désalloué par la fonction)
    void fusionner(bloc &r, bloc &h, bloc &g, bloc &d, const char blanc=' ')
    {
    	size_t 
    		x1 = g.x,
    		x2 = x1+h.x,
    		x3 = x2+d.x,
    		y1 = h.y,
    		y2 = (g.y>d.y) ? y1+g.y : y1+d.y;
    
    	allouer(r,x3,y2);
    
    	//------
    
    	size_t i, j;
    	for (j=0; j<y1; j++)
    	{
    		for (i=0; i<x1; i++)
    			r.tab[j][i]=blanc;
    		for (i=x1; i<x2; i++)
    			r.tab[j][i]=h.tab[j][i-x1];
    		for (i=x2; i<x3; i++)
    			r.tab[j][i]=blanc;
    	}
    
    	for (j=0; j<y2-y1; j++)
    	{
    		for (i=0; i<x1; i++)
    			r.tab[j+y1][i]=(g.y>j) ? g.tab[j][i] : blanc;
    		for (i=x1; i<x2; i++)
    			r.tab[j+y1][i]=blanc;
    		for (i=x2; i<x3; i++)
    			r.tab[j+y1][i]=(d.y>j) ? d.tab[j][i-x2] : blanc;
    	}
    
    	//------
    
    	liberer(g);
    	liberer(h);
    	liberer(d);
    }
    
    int main()
    {
    	bloc b;
    	{
    		bloc b1;
    		{
    			creer(b1,"*");
    		}
    		
    		bloc b2;
    		{
    			bloc b21;
    			{
    				creer(b21,"+");
    			}
    			
    			bloc b22;
    			{
    				creer(b22,"1.23");
    			}
    			
    			bloc b23;
    			{
    				creer(b23,"4.5");
    			}
    			
    			fusionner(b2,b21,b22,b23);
    		}
    		
    		bloc b3;
    		{
    			bloc b31;
    			{
    				creer(b31,"-");
    			}
    			
    			bloc b32;
    			{
    				bloc b321;
    				{
    					creer(b321,"/");
    				}
    				
    				bloc b322;
    				{
    					creer(b322,"6.7");
    				}
    				
    				bloc b323;
    				{
    					creer(b323,"8.9");
    				}
    				
    				fusionner(b32,b321,b322,b323);
    			}
    			
    			fusionner(b3,b31,b32);
    		}
    		
    		fusionner(b,b1,b2,b3);
    	}
    	
    	afficher(b);
    	
    	liberer(b);
    	
    	system("PAUSE");
    	return 0;
    }
    0
    1. sangoku12 Messages postés 39 Statut Membre
       
      il y a quelques erreurs que j'arrive pas à corriger!
      ce code fonctionne chez vous??
      0
    2. KX Messages postés 19031 Statut Modérateur 3 020
       
      Oui mais je l'ai compilé en C++ donc il peut y avoir quelques différences mais normalement ça devrait pas être grand chose... Quelles sont les erreurs affichées ?
      0
    3. sangoku12 Messages postés 39 Statut Membre
       
      ça fonctionne merci :)
      0
    4. sangoku12 Messages postés 39 Statut Membre
       
      Bonjour KX je sais que vous avez tors de mes questions mais quoi faire vous êtes le seul à pouvoir m'aider et je serai très reconnaissant si vous pourriez m'aider une dernière fois.
      voici la déclaration de ma structure

      --------------------------------------------------------------
      typedef float feuille;

      typedef struct s_noeud
      {char op_c;
      struct s_comp*filsg;
      struct s_comp*filsd;
      }noeud;

      typedef struct s_comp
      {int arite;
      union {noeud n;
      feuille f;
      }val;
      }composante;
      typedef float feuille;

      typedef struct s_noeud
      { char op_c;
      struct s_comp*filsg;
      struct s_comp*filsd;
      }noeud;

      typedef struct s_comp
      { int arite;
      union{ noeud n;
      feuille f;
      }val;
      }composante;

      typedef composante *lien;
      --------------------------------------------------------------
      j'ai une variable x qui pointe vers le sommet de mon arbre que j'ai déjà construit. ( lien x )
      j'ai pas arrivé à adapter le code que vous m'avez donné à ma structure et j'ai pas parvenu à afficher mon arbre
      le temps me presse et je vous prie de m'aider. un grand merci de toute façon
      0
    5. KX Messages postés 19031 Statut Modérateur 3 020
       
      Je n'adapterai pas mes blocs à ta structure de données ce soir, mais si tu comprends l'algo suivant (avec les exemples au dessus) tu devrais y arriver tout seul :

      bloc affichageArbre(Arbre a)
      {
      	bloc b
      
      	switch (a.arite)
      	{
      	case 0:	creer(b,a.operande)
      
      	case 1:	bloc b1
      		creer(b1,a.operateur)
      
      		bloc b2 = affichageArbre(a.gauche)
      
      		fusionner(b,b1,b2)
      
      	case 2:	bloc b1
      		creer(b1,a.operateur)
      
      		bloc b2 = affichageArbre(a.gauche)
      		bloc b3 = affichageArbre(a.droite)
      
      		fusionner(b,b1,b2,b3)
      	}
      
      	return b;
      }
      0