Correction TP Arbres A

Transcription

Correction TP Arbres A
// POLYTECH MARSEILLE - INFO3
// Algorithmique, Programmation & Structures de données I
// Année 2016-2017
// Les arbres : TP A
// =================
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<malloc.h>
<assert.h>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//
Types abstraits
===============
// pour les arbres
// --------------struct feuille {
int type ;
int val ;
char etiq ;
struct feuille *fg ;
struct feuille *fd ;
} ;
//
//
//
//
//
1 = feuille, 0 = noeud
valeur pour feuille
étiquette pour noeud
pointeur sur fils gauche
pointeur sur fils droit
typedef struct feuille t_feuille, * t_ptr_arbre, * tpf ;
// pour les files
// -------------typedef t_ptr_arbre data ;
typedef struct maillon
{
data donnee ;
struct maillon *suivant ;
} maillon ;
// Définit de type de donnée contenue dans un maillon
typedef maillon * t_ptr_file ;
// File = pointeur sur un maillon
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//
Fonctions abstraites pour les arbres
====================================
// Création d'une feuille de valeur val
// -----------------------------------t_ptr_arbre cree_feuille (int val)
{
tpf nouveau ;
nouveau = (tpf)malloc (sizeof(feuille)) ;
nouveau->type = 1 ;
nouveau->val = val ;
return nouveau ;
}
// Teste s'il s'agit d'une feuille ou d'un noeud
// --------------------------------------------int est_feuille (t_ptr_arbre arbre)
{
return arbre->type ;
}
// Renvoie la valeur d'une feuille
// ------------------------------int val_feuille (t_ptr_arbre arbre)
{
assert (est_feuille (arbre)) ;
return arbre->val ;
}
// Création d'un noeud
// ------------------t_ptr_arbre cree_noeud (char etiq, t_ptr_arbre fg, t_ptr_arbre fd)
{
tpf nouveau ;
nouveau = (tpf)malloc (sizeof(feuille)) ;
nouveau->type = 0 ;
nouveau->etiq = etiq ;
nouveau->fg = fg ;
nouveau->fd = fd ;
return nouveau ;
}
// Fils gauche
t_ptr_arbre arbre_fg (t_ptr_arbre arbre)
{
assert (!est_feuille (arbre)) ;
return arbre->fg ;
}
// Fils droit
t_ptr_arbre arbre_fd (t_ptr_arbre arbre)
{
assert (!est_feuille (arbre)) ;
return arbre->fd ;
}
// Etiquette d'un noeud
char arbre_etiq (t_ptr_arbre arbre)
{
assert (!est_feuille (arbre)) ;
return arbre->etiq ;
}
//
Fonctions abstraites pour les files
//
====================================
// Place un nouvel élément en queue de file
// ---------------------------------------//
// file[0] = pointeur de tête
// file[1] = pointeur de queue
void insere_file (data arbre, t_ptr_file file[])
{
t_ptr_file nouveau ;
nouveau = (t_ptr_file) malloc (sizeof(maillon)) ;
nouveau->donnee = arbre ;
nouveau->suivant = NULL ;
// création d'un maillon
if (file[0] == NULL) {
file[0] = nouveau ;
file[1] = nouveau ;
} else {
file[1]->suivant = nouveau ;
file[1] = nouveau ;
}
// premier maillon d'une file vide
}
// Retire l'élément en tête de file et renvoie son contenu
// ------------------------------------------------------data retire_file (t_ptr_file file[])
{
data val ;
t_ptr_file next ;
assert (file[0] != NULL) ;
val = file[0]->donnee ;
next = file[0]->suivant ;
free (file[0]) ;
file[0] = next ;
// nouveau maillon en queue de la file
return val ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//
Parcours en profondeur
======================
// sous forme prefixe
void profondeur_prefixe (t_ptr_arbre arbre, void action (t_ptr_arbre))
{
if (arbre) {
action (arbre) ;
if (!est_feuille (arbre)) {
profondeur_prefixe (arbre->fg, action) ;
profondeur_prefixe (arbre->fd, action) ;
}
}
return ;
}
// sous forme postfixe
void profondeur_postfixe (t_ptr_arbre arbre, void action (t_ptr_arbre))
{
if (arbre) {
if (!est_feuille (arbre)) {
profondeur_postfixe (arbre->fg, action) ;
profondeur_postfixe (arbre->fd, action) ;
}
action (arbre) ;
}
return ;
}
// sous forme infixe
void profondeur_infixe (t_ptr_arbre arbre, void action (t_ptr_arbre))
{
if (arbre) {
if (!est_feuille (arbre)) profondeur_postfixe (arbre->fg, action) ;
action (arbre) ;
if (!est_feuille (arbre)) profondeur_postfixe (arbre->fd, action) ;
}
return ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//
Parcours en largeur
===================
void largeur (t_ptr_arbre arbre, void action (t_ptr_arbre))
{
t_ptr_file file[2] ;
t_ptr_arbre ptr ;
if (arbre) {
file[0] = NULL ;
insere_file (arbre, file) ;
while (file[0] != NULL) {
ptr = retire_file (file) ;
action (ptr) ;
if (!est_feuille(ptr)) {
if(ptr->fg) insere_file (ptr->fg, file) ;
if (ptr->fd) insere_file (ptr->fd, file) ;
}
}
}
return ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
Autres exercices
//
================
// Nombre de noeuds d'un arbre
// --------------------------int nb_noeuds (t_ptr_arbre arbre)
{
if (arbre == NULL) return 0 ;
if (est_feuille(arbre)) return 0 ;
return 1+nb_noeuds(arbre->fg)+nb_noeuds(arbre->fd) ;
}
// Nombre de feuilles d'un arbre
// ----------------------------int nb_feuilles (t_ptr_arbre arbre)
{
if (arbre == NULL) return 0 ;
if (est_feuille(arbre)) return 1 ;
return nb_feuilles(arbre->fg)+nb_feuilles(arbre->fd) ;
}
// Hauteur d'un arbre
// -----------------int hauteur (t_ptr_arbre arbre)
{
int hg, hd ;
if (arbre == NULL) return 0 ;
if (est_feuille(arbre)) return 1 ;
hg = hauteur(arbre->fg) ;
hd = hauteur(arbre->fd) ;
if (hg >= hd) return 1+hg ;
return 1+hd ;
}
// Somme des feuilles d'un arbre
// -----------------------------
int somme_feuilles (t_ptr_arbre arbre)
{
if (arbre == NULL) return 0 ;
if (est_feuille(arbre)) return val_feuille (arbre) ;
return somme_feuilles(arbre->fg)+somme_feuilles(arbre->fd) ;
}
// Copie miroir d'un arbre
// ----------------------t_ptr_arbre miroir_arbre (t_ptr_arbre arbre)
{
if (arbre) {
if (est_feuille(arbre)) return cree_feuille (val_feuille(arbre)) ;
return cree_noeud (arbre_etiq(arbre), miroir_arbre(arbre_fd (arbre)), miroir_arbre(arbre_fg (arbre))) ;
}
return arbre ;
}
// Compte et imprime tous les sous-arbres
// -------------------------------------int tous_sous_arbres (t_ptr_arbre arbre, void action (t_ptr_arbre))
{
if (arbre) {
profondeur_prefixe (arbre, action) ;
printf ("\n") ;
if (est_feuille (arbre)) return 1 ;
return 1+tous_sous_arbres(arbre->fg, action)+tous_sous_arbres(arbre->fd, action) ;
}
return 0 ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//
Tests
=====
// Impression simple des noeuds et des feuilles
// --------------------------------------------
void traitement (t_ptr_arbre arbre)
{
if (est_feuille (arbre)) printf ("%d ", val_feuille(arbre)) ;
else printf ("%c ", arbre_etiq(arbre)) ;
}
// Impression dans le format de l'énoncé d'un arbre
// -----------------------------------------------void imprime_arbre_format_enonce (t_ptr_arbre arbre)
{
if (est_feuille (arbre)) printf ("%d", val_feuille (arbre)) ;
else {
printf ("(") ;
imprime_arbre_format_enonce (arbre_fg(arbre)) ;
printf ("%c", arbre_etiq(arbre)) ;
imprime_arbre_format_enonce (arbre_fd(arbre)) ;
printf (")") ;
}
return ;
}
// Enchainement des exercices pour un arbre
// ---------------------------------------void test (t_ptr_arbre arbre)
{
int n ;
printf ("\nprofondeur_prefixe : ") ;
profondeur_prefixe (arbre, traitement) ;
printf ("\nprofondeur_postfixe : ") ;
profondeur_postfixe (arbre, traitement) ;
printf ("\nprofondeur_infixe :
") ;
profondeur_infixe (arbre, traitement) ;
printf ("\nlargeur :
") ;
largeur (arbre, traitement) ;
printf ("\nnb_noeuds = %d", nb_noeuds(arbre)) ;
printf ("\nnb_feuilles = %d", nb_feuilles(arbre)) ;
printf ("\nhauteur = %d", hauteur(arbre)) ;
printf ("\nsomme_feuilles = %d", somme_feuilles(arbre)) ;
printf ("\n\nRecherche et comptage des sous-arbres\n") ;
n = tous_sous_arbres (arbre, traitement) ;
printf ("Nombre de sous-arbres = %d", n) ;
return ;
}
int main (void)
{
tpf n1, n2 ;
t_ptr_arbre arbre1, arbre2, arbre3, arbre4, arbre5, arbre6 ;
// Création d'arbres
arbre1 = cree_noeud( '+', cree_noeud( '*', cree_noeud( '+', cree_feuille( 1 ) , cree_feuille( 2 ) ) ,
cree_feuille( 3 ) ) ,
cree_noeud( '*', cree_feuille( 4 ) ,
cree_noeud( '*', cree_feuille( 5 ) , cree_feuille( 6 ) ) ) ) ;
n1 = cree_noeud ('+', cree_feuille (1), cree_feuille (2)) ;
n1 = cree_noeud ('+', n1, cree_feuille (3)) ;
n1 = cree_noeud ('+', n1, cree_feuille (4)) ;
n2 = cree_noeud ('*', cree_feuille (5), cree_feuille (6)) ;
n2 = cree_noeud ('+', n2, cree_feuille (7)) ;
arbre2 = cree_noeud ('+', n1, n2) ;
arbre3 = cree_noeud( '-', cree_noeud( '*', cree_feuille( 5 ) ,
cree_noeud( '+', cree_feuille( 6 ) , cree_feuille( 9 ) ) ) ,
cree_noeud( '/', cree_noeud( '*', cree_feuille( 16 ), cree_feuille( 2 ) ) ,
cree_noeud( '/', cree_feuille( 4 ) , cree_feuille( 2 ) ) ) ) ;
// Tests sur les arbres proposés
printf ("Premier arbre :\n") ;
imprime_arbre_format_enonce (arbre1) ;
test (arbre1) ;
arbre4 = miroir_arbre (arbre1) ;
printf ("\n\nEtude de l'arbre miroir :\n") ;
imprime_arbre_format_enonce (arbre4) ;
test (arbre4) ;
printf ("\n\nDeuxieme arbre :\n") ;
imprime_arbre_format_enonce (arbre2) ;
test (arbre2) ;
arbre5 = miroir_arbre (arbre2) ;
printf ("\n\nEtude de l'arbre miroir :\n") ;
imprime_arbre_format_enonce (arbre5) ;
test (arbre5) ;
printf ("\n\nTroisieme arbre :\n") ;
imprime_arbre_format_enonce (arbre3) ;
test (arbre3) ;
arbre6 = miroir_arbre (arbre3) ;
printf ("\n\nEtude de l'arbre miroir :\n") ;
imprime_arbre_format_enonce (arbre6) ;
test (arbre6) ;
return 0 ;
}