Vous êtes sur la page 1sur 23

INSAT – 2019-2020

Correction TD 4
Les arbres

1
Structure de données d’un arbre binaire

typedef struct arb


{
int val;
struct arb * fg;
struct arb * fd;

} arb;
typedef arb * arbre;

Exemple d’un arbre

2
Exercice 1: Arbre binaire de recherche

101, 144, 4096, 153, 3025, 2048 101, 153, 4096, 144, 3025, 2048 4096, 101, 144, 153, 3025, 2048

101 101 4096

144 153 101

4096 4096 144


144

153
153 3025

3025 3025
2048

2048 2048

3
Exercice 4

arbre ajouter(arbre A, int valeur)


{
if(A==NULL)
return(créer_noeud(valeur));
else
{
if(valeur<Aval)
Afg=ajouter(Afg,valeur);
else
if(valeur>Aval)
Afd=ajouter(Afd, valeur);
return(A);
}
}

4
arbre creer_noeud (int el)
{
arbre nod;
if (((nod)= (arbre ) malloc (sizeof(arb)))== NULL)

{ printf ("erreur allocation");


Exit(1);
}
else
{ nodval =el;
nod fg= NULL;
nod fd=NULL;
return(nod);
}
}

5
arbre fusion (arbre A1, arbre A2)
{
if(A2!=NULL)
{
A1=ajouter(A1, A2val);
A1=fusion(A1, A2fg);
A1=fusion(A1, A2fd);
}
return(A1);
}

6
arbre fusion (arbre A1, arbre A2) A1
{
if(A2!=NULL) 153
{
A1=ajouter(A1, A2val); 409
A1=fusion(A1, A2fg);
144

A1=fusion(A1, A2fd);
} 90
return(A1);
} A2
@1
140

@2 @3
145
80

7
A1

A1= fusion ( A1,@1)


153

{
409
if(@1!=NULL) 144
{
A1=ajouter(A1, @1val); 90
A1=fusion(A1, @1fg);
A1=fusion(A1, @1fd); A2
@1
} 140
return(A1); @2 @3
145
80
}
A1
153

409
144

90

140
8
A1
153

A1= fusion (A1,@1)


409
{ 144
if(@1!=NULL)
{ 90
A1=ajouter(A1, @1val);
A1=fusion(A1, @1fg); 140
A1=fusion(A1, @1fd);
} A2
return(A1); @1
140

} @2 @3
145
80
// @1fg correspond à @2

9
A1
153

A1= fusion (A1,@2) 409


{ 144

if(@2!=NULL)
{ 90
A1=ajouter(A1, @2val);
A1=fusion(A1, @2fg); 140

A1=fusion(A1, @2 fd); A2
} @1
return(A1);
140

@2 @3
145
} 80

153
A1
409
144

90

140
80 10
153 A1

A1= fusion (A1,@2) 409


{ 144

if(@2!=NULL)
{ 90
A1=ajouter(A1, @2val);
A1=fusion(A1, @2fg); 80 140

A1=fusion(A1, @2 fd);
} A2
return(A1); @1
140

} @2 @3
145
80
// @2fg correspond à NULL
// pas de modifications sur l’arbre

11
A1
153

A1= fusion (A1,@2) 409


{ 144

if(@2!=NULL)
{ 90
A1=ajouter(A1, @2val);
A1=fusion(A1, @2fg); 80 140

A1=fusion(A1, @2 fd);
} A2
return(A1); @1
140

} @2 @3
145
80
// @2fd correspond à NULL
// pas de modifications sur l’arbre

12
A1
153

A1= fusion (A1,@1) 409


{ 144

if(@1!=NULL)
{ 90
A1=ajouter(A1, @1val);
A1=fusion(A1, @1fg); 80 140

A1=fusion(A1, @1fd);
} A2
return(A1); @1
140

} @2 @3
145
80
// @1fd correspond à @3

13
A1
153

A1= fusion (A1,@3) 409


{ 144

if(@3!=NULL)
{ 90
A1=ajouter(A1, @3val);
A1=fusion(A1, @3fg); 80 140

A1=fusion(A1, @3fd); A2
} @1
return(A1); 140

@2 @3
} 80
145

A1
153

409
144

90 145

80 140 14
A1
153

A1= fusion (A1,@3) 409


{ 144

if(@3!=NULL)
{ 90 145
A1=ajouter(A1, @3val);
A1=fusion(A1, @3fg); 80 140

A1=fusion(A1, @3fd);
}
return(A1);
A2
@1
} 140

@2 @3
// @3fg correspond à NULL 80
145

// pas de modifications sur l’arbre

15
A1
153

A1= fusion (A1,@3) 409


{ 144

if(@3!=NULL)
{ 90 145
A1=ajouter(A1, @3val);
A1=fusion(A1, @3fg); 80 140

A1=fusion(A1, @3fd);
}
return(A1);
A2
@1
} 140

@2 @3
// @3fd correspond à NULL 80
145

// pas de modifications sur l’arbre

16
Exercice 2

La suppression d’un élément d’un arbre binaire de recherche consiste à


supprimer une valeur de l'arbre tout en conservant les propriétés de l’arbre
binaire de recherche. L'algorithme est le suivant (une fois trouvé le nœud
contenant la valeur en question) :

1- si le nœud à enlever ne possède aucun fils, on l'enlève,


2- si le nœud à enlever n'a qu'un fils, on le remplace par ce fils,
3- si le nœud à enlever a deux fils, on le remplace par le sommet de plus
petite valeur dans le sous-arbre droit, ou bien par le sommet de plus grande
valeur dans le sous arbre gauche puis on supprime ce sommet.

17
Remplacement de
Cas 1 Cas 2 la valeur du nœud Cas 3
à supprimer par la
140
153
valeur la plus 153
grande dans le
sous arbre gauche
80 145 144 144
409 409

90 90 150

40 140
140

150
145 153
144 409

90 409
90 150

40 140
Suppression du noeud 150
avec la couleur rouge
18
void supprimer(arbre *A, int val)
{
arbre t;
if(*A!=NULL)
{
if((*A)val==val)
{// 1er cas: feuille
if(((*A)fg==NULL)) &&((*A)fd==NULL))
{
t=*A;
*A=NULL;
free(t);
}
else if ((*A)fd==NULL)
{//2eme cas: Seulement un fils à gauche
t=*A;
*A=(*A)fg;
free(t);
}
19
else if ((*A)fg==NULL)
{//3eme cas: Seulement un fils à droite
t=*A;
*A=(*A)fd;
free(t);
}
else
{//4 eme cas : un fils à gauche et un fils à droite
// remplacer le nœud avec la valeur la plus
//grande dans le sous arbre à gauche
for (t=(*A)fg; tfd!=NULL; t=tfd);
(*A)val=tval;
supprimer(&((*A)fg),tval);
}
}
else if((*A)val>val)
supprimer(&((*A)fg),val);
else supprimer(&((*A)fd),val);
}
}
20
Exercice 3 A1 A2
a-
int est_equilibre(arbre A1, arbre A2) 140 140

{
if(A1==NULL) 80 145 80 145
return(A2==NULL);
if(A2==NULL)
return(0);
if(A1val==A2val)
return(est_equilibre(A1fg, A2fg)
&&est_equilibre(A1fd, A2fd));
return(0);

21
b-
Avant de présenter le code de la fonction qui permet de vérifier si un arbre
est inclus dans un autre, nous commençons par introduire la fonction
int est_equilibre_inc(arbre A1, arbre A2)

qui permet de tester si un arbre A2 est inclus dans un autre A1 à partir de la


racine en conservant la même structure.
A2
int est_equilibre_inc(arbre A1, arbre A2)
// tester si A2 est inclus dans A1 à partir de la racine 140

{
if(A2==NULL) 80 145
return(1);
if(A1==NULL) A1
return(0);
if(A1val==A2val) 140

return(est_equilibre_inc(A1fg, A2fg)
&&est_equilibre_inc(A1fd, A2fd)); 80 145
return(0);
} 60

22
160
A1

140 200
int est_inclus(arbre A1, arbre A2)
// tester si A2 est inclus dans A1
{ 80 145

if(A1==NULL)
return(0); 60
A2
if(A2==NULL)
return(1); 140
if(est_equilibre_inc(A1,A2))
return(1);
return(est_inclus(A1fg, A2)
80 145

||est_inclus(A1fd, A2));
}

23