Vous êtes sur la page 1sur 18

Chapitre 4

Structure d'arbre

4.1 Dénition
Un arbre est un graphe connexe sans cycle, non orienté et qui commence
par une racine r, la structure d'arbre induit une partition sur l'ensemble des
n÷uds de l'arbre. En d'autres termes, un arbre est un ensemble de n÷uds
(sommets), un n÷ud contient une information, il est relié avec un n÷ud père
et peut avoir de 0n ls, remarquant qu'il y'a un n÷ud qui n'a pas de père on
l'appel la racine de l'arbre.

taille d’arbre= 15
nombre de feuille= 9
racine
hauteur = 4
nombre de noeuds internes=5

noeud interne 47

11 20 38 51

5 14 1 14 36 39 49 feuille

Figure 4.1  un exemple d'arbre avec ses caractéristiques

1
Vocabulaire et propriétés de la structure arbre

 Un arbre (tree ) de n sommet a n − 1 arêtes


 Il existe qu'un seul arête entre deux n÷uds les reliant.
 La taille d'un arbre est le nombre de n÷ud (number of node ) de
l'arbre.
 Un n÷ud peut avoir 0 à plusieurs ls, la racine n'a pas de père.
 Une feuille (leaves ) est un n÷ud qui n'a pas de successeurs (ls), les
autres n÷uds sont appelés n÷uds internes
 La hauteur (height) d'un arbre est la longueur du plus long chemin à
partir de la racine
 Un n÷ud n est dit accessible à partir d'un n÷ud n0 s'il existe un chemin
allant de n0 à n dans l'arbre.
Dans le cas général, un arbre est appelé arbre à n-aires (gure ; mais ils
existent autres types peuvent être considérés comme des cas spéciaux, dans
ce cours on s'intéresse par les arbres binaires (Binary trees, gure 4.1).

4.2 Arbre binaire


Un arbre binaire est une structure de données récursive qui peut être
représenter sous forme hiérarchique formé par des n÷uds, le n÷ud initial
étant appelé racine. Une des propriétés des arbres binaires est que chaque
n÷ud possède au plus deux éléments ls au niveau inférieur, habituellement
appelés ls gauche et ls droit. Du point de vue de ces ls, le n÷ud dont ils
sont issus au niveau supérieur est appelé père.
Au niveau le plus élevé il y a donc un n÷ud racine. Au niveau directement
inférieur, il y a au plus deux n÷uds ls. Un n÷ud n'ayant aucun ls est appelé
feuille. Le nombre de niveaux total, autrement dit la distance entre la feuille
la plus éloignée et la racine, est appelé hauteur de l'arbre. Le niveau d'un
n÷ud est appelé profondeur de n÷ud. On peut utiliser les arbres binaires en
tant que arbre binaire de recherche.

4.2.1 Implémentation d'un arbre binaire

L'implémentation la plus simple d'un arbre binaire est illustrée dans le


listing
type a r b r e = ^abr
abr = e n r e g i s t r e m e n t
noeud : e n t i e r ;

2
gauche , d r o i t e : a r b r e
Listing 4.1  Impléméntation d'un arbre binaire

4.2.2 Parcours d'arbre

Le parcours d'arbre est une façon d'ordonner les n÷uds d'un arbre an de
les parcourir. le résultat du parcours d'un arbre est une liste d'éléments qui
n'est pas souvent explicite . On distingue deux types essentiels de parcours :
en profondeur ou en largeur. Dans les parcours en profondeur on distingue
à nouveau le parcours préxe(pré-ordre), le parcours inxe (in-ordre) et le
parcours suxe(post-ordre), dans la suite on utilise l'arbre de la gure 4.2 .

2 4

3 5 0

6 7 9

Figure 4.2  Parcours d'arbre binaire

4.2.3 Parcours d'arbre en profondeur

Ce parcours, tient toujours à visiter le n÷ud le plus éloigné de la racine


que possible, à la condition qu'il soit le ls d'un n÷ud déjà visité. À l'opposé
des parcours en profondeur sur les graphes, il n'est pas nécessaire de connaître
les n÷uds déjà visités, car un arbre ne contient pas de cycles. Les parcours
préxe, inxe et postxe sont des cas particuliers de ce type de parcours.
Dans ce parcours, sa version itérative doit conserver une liste des éléments
en attente de traitement. La liste utilisée dans ce parcours doit avoir une
structure de pile (de type LIFO, Last In, First Out ).

3
Parcours préxe
Le parcours préxe ache les valeurs de l'arbre en pré-ordre. C'est à dire
on visite la racine ainsi que le ls gauche puis le ls droit, il faut bien noter
que cette procédure est récursive.

Procédure parcours − pref ix( A : arbre)


Début
ecrire(A ∧ .noeud) parcours − pref ix(A ↑ .gauche) ;
Si (non(arbre − vide(A ↑ .gauche))) Alors
parcours − pref ix(A ↑ .gauche) ;
Fin Si
Si (non(arbre − vide(A ↑ .droite))) Alors
parcours − pref ix(A ↑ .droite) ;
Fin Si

Fin

Algorithme 1  Parcours préxe d'un arbre binaire

1 1

2 4
2
3 6 7

3 5 0
4 8

6 5 7 9

Chaine de parcours préfixe= 1, 2, 3, 5, 6, 7, 4, 0, 9

Figure 4.3  Parcours préxe

4
Parcours inxe
Le parcours inxe (in ordre) explore le sous-arbre gauche, la racine et le
sous-arbre droit

Procédure parcours − inf ix( A : arbre)


Début
Si (non(arbre − vide(A ↑ .gauche))) Alors
parcours − inf ix(A ↑ .gauche) ;
Fin Si
ecrire(A ↑ .noeud)
Si (non(arbre − vide(A ↑ .droite))) Alors
parcours − inf ix(A ↑ .droite) ;
Fin Si

Fin

Algorithme 2  Parcours inxe d'un arbre binaire

1 6

2 4
1
5

3 2 5 7 0
3
4 8

6 7 9

Chaine de parcours infixe= 3, 2, 6, 5, 7, 1, 4, 9, 0

Figure 4.4  Parcours inxe

5
Parcours postxe
Le parcours en postxe permet de visiter le sous-arbre gauche, le sous-
arbre droit et puis la racine.

Procédure parcours − postf ix( A : arbre)


Début
Si (non(arbre − vide(A ↑ .gauche))) Alors
parcours − postf ix(A ↑ .gauche) ;
Fin Si
Si (non(arbre − vide(A ↑ .droite))) Alors
parcours − postf ix(A ↑ .droite) ;
Fin Si
ecrire(A ↑ .noeud)
Fin

Algorithme 3  Parcours postxe d'un arbre binaire

1 6

2 4
1
5

3 2 5 7 0
3
4 8

6 7 9

Chaine de parcours infixe= 3, 2, 6, 5, 7, 1, 4, 9, 0

Figure 4.5  Parcours postxe

4.2.4 Parcours d'arbre en largeur

Dans le parcours en largeur on parcourt l'arbre niveau par niveau. Les


n÷uds de niveau 0 sont sont d'abord parcourus puis les n÷uds de niveau 1

6
et ainsi de suite. Dans chaque niveau, les n÷uds sont parcourus de la gauche
vers la droite. Au Contraire du parcours en profondeur, ce parcours essaie
toujours de visiter le n÷ud le plus proche de la racine qui n'a pas déjà été
visité. En suivant ce parcours, on va d'abord visiter la racine, puis les n÷uds
à la profondeur 1, puis 2, etc. D'où le nom parcours en largeur.

La structure de le d'attente (de type FIFO, First in, rst out ), ce qui
induit que l'ordre de sortie n'est pas le même (i.e. on permute gauche et
droite dans le traitement).

P ro c ed u re P a r c o u r s L a r g e u r (A: a r b r e ) {
// i n i t i a l i s a t i o n de l a f i l e
e n f i l e r ( Racine (A) , f )
Tant que ( f <> n i l ) { // l a f i l e n ' e s t pas v i d e
noeud = d e f i l e r ( f )
e c r i r e ( noeud )
S i ( noeud ^ . gauche ) <> n i ) A l o r s
e n f i l e r ( noeud ^ . gauche , f )
S i ( noeud ^ . d r o i t e ) <> n i l ) A l o r s
e n f i l e r ( noeud ^ . d r o i t e , f )
}
}

Listing 4.2  parcours en largeur

7
Procédure W ideSearch( A : arbre)
Dbut
init(F ) f = F ileV ide;
enf iler(A ↑ .noeud, f );
Tant que (not(f ile − vide(f ))) faire
n = def iler(f );
ecrire(n);
Si (A ↑ .gauche 6= nil)) Alors
enf iler(A ↑ .gauche, f )
Fin Si
Si (A ↑ .droite 6= nil)) Alors
enf iler(A ↑ .droite, f )
Fin Si
Fait
Fin

Algorithme 4  Parcours en largeur d'un arbre binaire

4.2.5 Calcul de la hauteur d'un arbre

On peut dénir cette fonction récursivement comme suit :

 un arbre vide est de hauteur 0


 un arbre non vide a pour hauteur 1 + la hauteur maximale entre le
sous arbre gauche et le sous arbre droit.

A partir de cette dénition l'algorithme 5 illustre le calcul de la hauteur


d'arbre binaire.

8
Fonction Height( A : arbre) : entier
Dbut
Si (arbre − vide(A)) Alors
Height ← 0 ;
Sinon
Height ← 1 + max(Height(A.gauche), Height(A.droite)) ;
Fin Si

Fin

Algorithme 5  Calcul de hauteur d'un arbre

4.2.6 Calcul de taille d'un arbre

Comme la hauteur de l'arbre, le calcul de la taille de l'arbre c'est à dire


le nombre de n÷ud se calcule récursivement selon la dénition suivante :
 La taille d'un arbre vide est 0
 La taille d'un arbre qui n'est pas vide est égale à 1 + la taille du sous
arbre gauche + taille du sous arbre droit.
L'algorithme 6 montre comment la taille de l'arbre est calculé.

Fonction N BN ode( A : arbre) : entier


Dbut
Si (arbre − vide(A)) Alors
N BN ode ← 0 ;
Sinon
N BN ode ← 1 + N BN ode(A.gauche) + N BN ode(A.droite) ;
Fin Si

Fin

Algorithme 6  Calcul de la taille d'un arbre

4.2.7 Calcul de nombre de feuilles dans un arbre

Pour calculer le nombre de feuilles on prend la dénition récursive :


 Un arbre vide ne contient aucune feuille.

9
 Le nombre de feuille dans un arbre non vide est déni de la façon
suivante : Dans le cas où le n÷ud est une feuille alors on renvoie 1,
si c'est un n÷ud interne alors le nombre de feuille est la somme du
nombre de feuille de chacun de ses deux ls.
Ainsi l'algorithme 7 calcul le nombre de feuille dans l'arbre avec f euille(A)
vérié si le n÷ud est une feuille.

Fonction nbleaves( A : arbre) : entier


Dbut
Si (arbre − vide(A)) Alors
nbleaves ← 0 ;
Sinon
Si (f euille(A)) Alors
nbleaves ← 1 ;
Sinon
nbleaves ← nbleaves(A.gauche) + nbleaves(A.droite) ;
Fin Si
Fin Si

Fin

Algorithme 7  Calcul de la taille d'un arbre(nombre de n÷ud)

4.2.8 Calcul de nombre de n÷uds internes

Un n÷ud interne est déni par un n÷ud qui n'est pas racine et n'est
pas feuille, l'algorithme 8 traduit la dénition récursive du calcul de n÷uds
internes suivante :
 un arbre vide n'a pas de n÷ud interne.
 si le n÷ud en cours est une feuille alors renvoyer 0
 si le n÷ud a au moins un ls, renvoyer 1 plus la somme des n÷uds
interne des ls.

10
Fonction internalN ode( A : arbre) : entier
Début
Si (arbre − vide(A)) Alors
internalN ode ← 0 ;
Sinon
Si (f euille(A)) Alors
internalN ode ← 0 ;
Sinon
internalN ode ← 1 + internalN ode(A.gauche) +
internalN ode(A.droite) ;
Fin Si
Fin Si

Fin

Algorithme 8  Calcul de nombre de n÷uds internes d'un arbre

4.3 Arbre n-aires


Un arbre de n-aires est une généralisation des arbres binaires, à la dié-
rence de nombres de ls qu'on peut trouver jusqu'à n ls alors que l'arbre
binaire peut avoir au plus deux ls.

4.3.1 Implémentation

L'implémentation d'un arbre à n-aires peut avoir deux situations dié-


rentes, la première quand le nombre de ls est connu la structure de données
devient un n÷ud qui pointe vers un tableau de n ls, la deuxième situation
quand le nombre de ls est inconnu ou on veut optimiser l'espace mémoire,
l'implémentation de cette dernière est que chaque n÷ud pointe vers le pre-
miers ls et vers son frère, comme le montre la gure 4.6

4.4 Arbre binaire de recherche


Un arbre binaire de recherche (ou ABR) est un arbre binaire qui permet
de représenter un ensemble de valeurs disposant d'une relation d'ordre sur
ces valeurs de tel façon que les n÷uds du sous arbre gauche sont inférieurs

11
Arbre de n-aires /n est inconnu Vue de l’implementation

Figure 4.6  Implémentation d'arbre n-aires

aux n÷uds du sous arbre droit. Les opérations de base sur les arbres binaires
de recherche sont l'insertion, la suppression, et la recherche d'une valeur.
La gure 4.7 illustre un exemple d'un arbre binaire de recherche, pour
avoir une chaine ordonnée on doit acher les éléments de l'arbre par un
parcours inxe, ainsi la localisation de la plus petite valeur ou le minimum ici
c'est 5 dans l'arbre est obtenu par une descente vers les ls à gauche jusqu'au
dernier qui est le minimum, et c'est applicable aussi pour le maximum qui
est situé dans l'extrême droit dans l'exemple de la gure : 51.

33

15 47

10 20 38 51

5 18 36 39 49

Figure 4.7  Exemple d'un ABR

4.4.1 Insertion d'un élément

Pour insérer une valeur on commence par une recherche : on cherche la


valeur du n÷ud à insérer ; lorsqu'on arrive à une feuille, on ajoute le n÷ud
comme ls de la feuille en comparant sa valeur à celle de la feuille : si elle
est inférieure, le nouveau n÷ud sera à gauche ; sinon il sera à droite. Le
code d'insertion illustré dans l'algorithme 9 s'exécute récursivement, avec une
remarque qu'il faut retenir, l'élément inséré est toujours une feuille.

12
Procédure InsertionABR( valeur : entier,var A: arbre)
Début
Si (arbre − vide(A)) Alors
cre − arbre(A, nil, nil) ;
Sinon
Si (valeur>A.noeud) Alors
InsertionABR(valeur, A.droite
Sinon
Si (valeur<A.noeud) Alors
InsertionABR(valeur, A.gauche
Fin Si
Fin Si
Fin Si

Fin

Algorithme 9  Insertion dans un ABR

Dans l'exemple de la gure 4.7 on veut insérer la valeur 4 dans l'arbre,


après la recherche de son emplacement le mieux adéquat, puisque 4 est une
valeur inférieur à la racine 33 encerclé en blue on l'insère dans le sous arbre
gauche ainsi de suite jusu'a trouver la feuille où insérer la valeur 4 (voir gure
4.8).

33

15 47

10 20 38 51

5 18 36 49
insertion de 4

Figure 4.8  Insertion de la valeur 4 dans l'ABR

13
4.4.2 Recherche d'un élément

Pour rechercher une valeur dans un ABR, il faut parcourir une branche à
partir de la racine, en descendant chaque fois sur le ls gauche ou sur le ls
droit suivant que la valeur du n÷ud encourt est plus grande ou plus petite
que la valeur cherchée. On arrête la recherche si la valeur est trouvée ou
si on atteint une feuille donc l'élément n'existe pas, l'algorithme 10 montre
comment la recherche est faite dans un ABR de façon récursive.

Fonction rechercher( valeur : entier, A : arbre) : booléen


Début
Si (arbre − vide(A)) Alors
recherche ←− f aux ;
Sinon
Si (valeur = A.noeud) Alors
recherche ←− vrai ;
Sinon
Si (valeur>A.noeud) Alors
rechercher(valeur, A.droite)
Sinon
rechercher(valeur, A.gauche)
Fin Si
Fin Si
Fin Si

Fin

Algorithme 10  Recherche d'une valeur dans un ABR

En utilisant l'exemple de la gure 4.7 pour chercher la valeur 39, en


comparant la valeur recherchée par le n÷ud en court à partir de la racine, on
trouve 39 alors que 17 est normalement située à gauche de 18 qui n'est pas
les cas (voir gure 4.11.

4.4.3 Successeur d'un n÷ud

Le successeur d'un n÷ud p dans un arbre A si il existe, est le n÷ud de n


qui a la valeur la plus petite des valeurs qui gurent dans l'arbre A et qui est
plus grand que la valeur de p. Si p possède un ls droit, son successeur est
le n÷ud d'extrême gauche dans le sous-arbre droit. Si p n'a pas de ls droit

14
33

15 47

10 20 38 51

5 18 36 39 49

33

15 47

10 20 38 51

5 18 36 39 49

Figure 4.9  Recherche de la valeur 39 et 17 dans l'ABR

15
alors le successeur de p est le premier de ses ascendants tel que p apparait
dans son sous-arbre gauche. Si cet ascendant n'existe pas c'est que p a la plus
grande valeur dans l'arbre. La gure 4.10, montre le successeur de la valeur
33 qui est le n÷ud de l'extrême gauche du sous arbre droit c'est à dire 36,
alors que le n÷ud 20 qui n'a pas de ls droit doit chercher dans ses ancêtre
que 20 apparait dans son sous arbre( pour 33, 20 est le plus proche).

33

15 47

10 20 38 51

5 18 36 39 49

Figure 4.10  Exemple de successeur de 20 et de 33

4.4.4 Suppression d'un élément

Pour cette opération on peut avoir trois situation selon le nombre de ls :

Supprimer une feuille : dans ce cas on supprime le ls directement puis-


qu'il n'a pas de successeur
Supprimer un n÷ud avec un seul ls :
Supprimer un n÷ud avec deux ls : Soit un n÷ud qu'on veut suppri-
mer appelé N (le n÷ud de valeur 33 rempli en rouge dans la gure ??).
Pour eectuer la suppression de N il faut l'échanger avec son succes-
seur (arrondi en blue) le plus proche (le n÷ud le plus à gauche du
sous-arbre droit, le n÷ud de valeur 36) ou son plus proche prédécesseur
(le n÷ud le plus à droite du sous-arbre gauche, le n÷ud de valeur 30).
Cela permet de garder l'ordre de l'arbre binaire de recherche. Puis on
applique à nouveau la procédure de suppression à N , qui est maintenant
une feuille ou un n÷ud avec un seul ls.

16
33

15 47

10 20 38 51

18 30 36 39 49

36

15 47

10 20 38 49

18 30 39

Figure 4.11  Suppression de la valeur 33, 5 et 51 dans l'ABR

17
4.4.5 Algorithme d'équilibrage d'ABR

4.5 Application des arbres

18