Afficher un arbre

Résolu/Fermé
sangoku12 Messages postés 31 Date d'inscription mercredi 10 août 2011 Statut Membre Dernière intervention 9 mai 2013 - 3 sept. 2011 à 11:32
sangoku12 Messages postés 31 Date d'inscription mercredi 10 août 2011 Statut Membre Dernière intervention 9 mai 2013 - 14 sept. 2011 à 16:47
Bonjour,

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

2 réponses

KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
3 sept. 2011 à 15:53
Ç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
sangoku12 Messages postés 31 Date d'inscription mercredi 10 août 2011 Statut Membre Dernière intervention 9 mai 2013
7 sept. 2011 à 18:04
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
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 7/09/2011 à 18:08
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
sangoku12 Messages postés 31 Date d'inscription mercredi 10 août 2011 Statut Membre Dernière intervention 9 mai 2013
7 sept. 2011 à 18:17
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
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
7 sept. 2011 à 18:21
Les entiers aussi n'ont qu'un seul chiffre ?
Et quel est ta structure d'arbre (ton langage de programmation, ton type arbre...)
0
sangoku12 Messages postés 31 Date d'inscription mercredi 10 août 2011 Statut Membre Dernière intervention 9 mai 2013
7 sept. 2011 à 18:29
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
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
8 sept. 2011 à 10:19
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
sangoku12 Messages postés 31 Date d'inscription mercredi 10 août 2011 Statut Membre Dernière intervention 9 mai 2013
10 sept. 2011 à 15:19
il y a quelques erreurs que j'arrive pas à corriger!
ce code fonctionne chez vous??
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
10 sept. 2011 à 15:22
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
sangoku12 Messages postés 31 Date d'inscription mercredi 10 août 2011 Statut Membre Dernière intervention 9 mai 2013
10 sept. 2011 à 21:13
ça fonctionne merci :)
0
sangoku12 Messages postés 31 Date d'inscription mercredi 10 août 2011 Statut Membre Dernière intervention 9 mai 2013
Modifié par sangoku12 le 14/09/2011 à 00:27
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
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
14 sept. 2011 à 01:30
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