Académique Documents
Professionnel Documents
Culture Documents
Plan
1. Dfinitions
2. Arbres binaires
3. Arbres de recherche binaires
4. Implmentation en contigu
5. Quelques exemples d'application des arbres binaires
6. Arbres m-aire
1) Dfinitions
Un arbre est une structure de donnes (souvent dynamique) reprsentant un ensemble de valeurs
organises hirarchiquement. Chaque valeur est stocke dans un nud. Les nuds sont connects
entre eux par des relations parents.
A part le nud racine, tous les autres nuds ont exactement un seul nud parent et zro ou
plusieurs nuds fils.
Le nud racine n'a pas de parent et possde zro ou plusieurs fils.
Les nuds qui n'ont pas de fils sont appels feuilles (ou nuds externes), les autres (ceux qui ont au
moins un fils) sont appels nuds internes.
Niveaux
0
racine
d
f
g
j
h
k
i
l
Dans l'exemple de la figure ci-dessus, la racine de l'arbre est le nud contenant l'information 'a'.
Les feuilles de cet arbres sont les nuds contenant respectivement les informations suivantes :
'e', 'c', 'f', 'j', 'k', 'h' et 'l'
Les nuds contenant les informations 'j' et 'k' sont les fils du nud contenant 'g' qui est aussi le fils
du nud contenant 'd', lui mme le fils de la racine.
Les nuds issus d'un mme parent direct sont des nuds frres. Dans l'exemple prcdent, les
nuds contenant 'b', 'c' et 'd' sont frres, de mme que ceux contenant 'f', 'g', 'h' et 'i'. Les nuds
contenant 'j' et 'k' sont aussi des frres.
Une branche est une suite de nuds connects de pre en fils (depuis le nud racine jusqu' une des
Hidouci W.K. / Les Arbres / Structures de donnes / ALSDD / ESI
feuille de l'arbre). Par exemple a-b-e est une branche de l'arbre prcdent, de mme que a-c, a-d-f,
a-d-g-j, ...etc.
Le niveau d'un nud est la distance qui le spare de la racine. Par exemple, dans la figure
prcdente, le niveau du nud contenant 'g' est gal 2.
La profondeur d'un arbre (ou sa hauteur) est le plus grand niveau (c-a-d la distance entre la racine et
la feuille la plus loigne). Dans l'exemple prcdent, la profondeur de l'arbre est gal 3.
- Dfinition rcursive d'un arbre
Cas particulier:
NIL est un arbre (l'arbre vide, contenant zro nud)
Cas gnral:
si n est un nud et si T1, T2, ...Tm sont des arbres, alors on peut construire un nouvel arbre
en connectant T1, T2, ...Tm comme des fils n. chaque Ti est dfinit de la mme manire
(rcursivement).
Dans ce cas, T1, T2, ... Tm sont des sous-arbres de n. De plus tout sous-arbre d'un sous-arbre
de n est aussi un sous-arbre de n.
Les descendants d'un nud n sont tous les nuds appartenant aux sous-arbres de n. Dans l'exemple,
les descendants de d sont : f,g,h,i,j,k et l.
Les ascendants d'un nud, sont tous les nuds dont il est descendant. Dans l'exemple, les
ascendants de k sont : g,d et a.
Le degr d'un nud est le nombre de ses fils. Par exemple le degr de d est 4, celui de a est 3 alors
que le degr de c est 0.
Une fort est un ensemble d'arbres.
2) Arbres binaires
Un arbre binaire est un arbre o chaque nud est connect deux sous-arbres (un sous-arbre
gauche et un sous-arbre droit). Ainsi le premier fils d'un nud n est appel fils-gauche (fg) et le
deuxime fils est appel fils-droit (fd).
a
b
fg
fg
fd
fd
fd
fg
d
e
fg
fd
NIL
j
l
Dans cet exemple (la figure ci-dessus), le fils-droit du fils-gauche de la racine est un arbre vide (le
NIL droite de b). De mme le sous-arbre droit de la racine est un arbre binaire de racine un nud
contenant l'information 'c'... etc.
Un arbre binaire est dit 'strictement binaire' si chaque nud interne a exactement 2 fils diffrents de
NIL. (voir fig. ci-dessous)
d
e
f
b
j
a
Dans un arbre strictement binaire, le nombre de feuilles est toujours gal au nombre de nuds
internes + 1. Dans l'exemple prcdent, il y a 4 feuilles (e, a, l et b) et 3 nuds internes (d, f et j).
Un arbre binaire est dit 'complet' (ou compltement quilibr), s'il est strictement binaire et si toutes
les feuilles se trouvent au mme niveau :
d
e
a
f
l
Le nombre de nuds dans un niveau i est donc toujours = 2 fois le nombre de nuds du niveau
prcdent (i-1), pour tout i entre 1 et d.
Dans un arbre binaire complet de profondeur d :
le nombre total de nuds = 20 + 21 + 22 + ... 2d = 2d+1-1
le nombre de nuds internes = 2d-1
le nombre de feuilles = 2d
le nombre de nuds dans le niveau i = 2i
Ainsi on peut tablir une quation entre la profondeur (d) d'un arbre binaire complet et le nombre
total de nuds (n) : d = log2(n+1) 1
- Modle des arbres binaires
Dans les oprations formant le modle des arbres binaire, les paramtres p et q sont des pointeurs
vers des nuds alors que v est un type quelconque (l'information ou la valeur du nud).
Le nud est alors form d'au moins trois champs : l'information (typeqlq), le fg (ptr) et le fd (ptr).
Hidouci W.K. / Les Arbres / Structures de donnes / ALSDD / ESI
T2
a) Le parcours prordre de n (s'il n'est pas vide) consiste visiter le nud racine (n) ensuite
parcourir rcursivement en prordre les sous-arbres T1 puis T2 [ n , T1 , T2 ].
Voici une procdure (rcursive) qui affiche les valeurs (informations) de tous les nuds d'un arbre
de racine R en le parcourant en prordre :
preordre( R:ptr )
debut
SI R <> NIL
ecrire( info(R) );
preordre( fg(R) );
preordre( fd(R) )
FSI
fin
b) Le parcours inordre de n (s'il n'est pas vide) consiste d'abord parcourir rcursivement en
inordre le sous-arbre gauche T1, puis visiter le nud racine (n) ensuite parcourir rcursivement en
inordre le sous-arbre droit T2 [ T1 , n , T2 ].
Voici une procdure (rcursive) qui affiche les valeurs (informations) de tous les nuds d'un arbre
de racine R en le parcourant en inordre :
inordre( R:ptr )
debut
SI R <> NIL
inordre( fg(R) );
ecrire( info(R) );
inordre( fd(R) )
FSI
fin
c) Le parcours postordre de n (s'il n'est pas vide) consiste d'abord parcourir rcursivement en
postordre les sous-arbres T1 puis T2 ensuite visiter le nud racine (n) [ T1 , T2 , n ].
Voici une procdure (rcursive) qui affiche les valeurs (informations) de tous les nuds d'un arbre
de racine R en le parcourant en postordre :
postordre( R:ptr )
debut
SI R <> NIL
postordre( fg(R) );
postordre( fd(R) );
ecrire( info(R) )
FSI
fin
Exemple :
Si on applique ces trois parcours sur l'arbre ci-dessous :
a
c
d
f
i
k
j
l
<
<
>
59
71
>
>
10
33
<
8
>
<
27
20
>
55
<
52
Pour rechercher une valeur v dans un arbre de recherche R, l'algorithme est simple et rapide :
Si l'arbre est vide (R=NIL), on s'arrte (v n'existe pas)
Sinon on compare v avec l'information de la racine (info(R)) :
Si c'est gal, on s'arrte (v existe dans R)
Sinon Si c'est infrieur, on continue rcursivement dans le sous-arbre gauche de R
Sinon c'est suprieur, on continue rcursivement dans le sous-arbre droit de R
On remarque que le parcours inordre d'un arbre de recherche, permet de lister les valeurs de l'arbre
en ordre croissant. Donc le premier nud en inordre contient la plus petite valeur de l'arbre de
recherche, et le suivant inordre de n contient le successeur en ordre croissant de la valeur info(n).
Pour l'arbre de la figure prcdente, le parcours inordre donne la liste ordonne suivante :
3, 5, 8, 10, 15, 20, 27, 33, 52, 55, 59, 71.
Les oprations d'insertion et de suppression dans un arbre de recherche doivent maintenir la
proprit des arbres de recherche :
Pour insrer une valeur v dans un arbre de recherche R, on commence par rechercher v pour
s'assurer qu'elle n'existe pas dj dans R (pas de double) et pour localiser l'endroit o elle doit tre
insre. Soit p le dernier nud visit par la recherche, on cre alors un nouveau nud n contenant v
et on connecte n comme fils-gauche de p si v < info(p) ou comme fils droit de p si v > info(p).
Par exemple si on veut insrer 25 dans l'arbre de la figure prcdente, on commence par rechercher
25, et voici le droulement (textuel) de cette recherche :
Hidouci W.K. / Les Arbres / Structures de donnes / ALSDD / ESI
- on compare 25 par rapport 20 (la racine), c'est suprieur, on descend donc droite,
- on compare 25 par rapport 59, c'est infrieur, on descend gauche,
- on compare 25 par rapport 27, c'est infrieur, on descend encore gauche et on trouve NIL,
- on s'arrte ce niveau, 25 n'existe pas et le dernier nud visit (p) est celui contenant 27.
Pour insrer 25, il suffit alors de crer un nouveau nud (n) contenant 25 comme information, et le
connecter comme fils-gauche de p (car 25 est infrieure 27).
La figure ci-dessous schmatise cette dernire phase :
20
59
15
p
5
3
10
25
71
27
33
55
8
52
L'insertion dans un arbre de recherche cre toujours une nouvelle feuille. L'arbre grandit vers le
bas.
Pour supprimer une valeur v dans un arbre de recherche binaire R, on commence par la rechercher
pour trouver le nud (n) qui la contient, ensuite on procde la suppression suivant l'un des deux
cas suivants :
a) Si n est une feuille ou bien un nud interne qui ne possde qu'un seul fils diffrent de NIL, on
peut alors supprimer n en mettant jour son pre (le champs fg ou fd) pour remplacer n soit par
NIL (si c'tait une feuille), soit par l'adresse de l'unique fils de n (sinon).
b) Si n est un nud avec deux fils diffrents de NIL, on remplace v l'intrieur de n par son
successeur en ordre croissant et on supprime le nud qui contenait ce successeur. Comme le
successeur de v se trouve dans le suivant inordre de n, il est facile de le localiser, il suffit de
descendre une fois droite de n, puis descendre le plus gauche possible, jusqu trouver un nud
dont le fg est NIL. On remarque dans ce cas que le successeur inordre de n ne peut pas tre un
nud avec 2 fils diffrents de NIL, puisque au moins son fils-gauche doit tre gal NIL.
Par exemple, si on supprime 33 dans l'arbre prcdent, on modifie le nud contenant 27 pour point
directement celui contenant 55 :
20
59
15
71
27
33
25
10
55
8
52
Si on supprime la valeur 5 dans l'arbre ci-dessus, on est alors dans le 2e cas (un nud avec deux fils
diffrents de NIL), il faut donc remplacer la valeur 5 par son successeur (8), qui se trouve dans le
nud le plus gauche du sous-arbre droit de 5. Le nud contenant 8 sera bien sr supprim pour ne
pas garder de double.
On obtient alors l'arbre suivant :
20
59
15
10
8
71
27
5 8
25
55
52
Toutes les oprations que l'on vient de voir (recherche, insertion et suppression) sont efficaces
(rapides) si l'arbre binaire est quilibr (ou presque), car la profondeur serait alors logarithmique en
fonction du nombre de nuds (valeurs). Par exemple, dans un arbre de recherche binaire quilibr
contenant 1000 valeurs, il faudrait au maximum 10 tests (ou itrations) pour une recherche,
insertion ou suppression. De mme qu'il en faudrait 20 tests si l'arbre renfermait 1 000 000 de
valeurs, ...etc.
Le problme est que rien n'assure que l'arbre restera toujours quilibr (ou presque), si par exemple
on insre, dans un arbre initialement vide, une suite ordonne de 1000 valeurs, le rsultat obtenu
sera un arbre compltement 'dgnr' qui ressemble en fait une simple liste linaire chane de
1000 maillons. Dans ce cas, le cot des oprations d'accs deviendra linaire (proportionnel au
nombre de valeur), et par exemple une recherche dans un tel arbre cotera au maximum 1000 tests,
alors que dans un arbre dgnr d'un million de valeurs, le cot sera d'un million de tests, ...etc.
Il existe d'autres algorithmes d'insertion et de suppression (un peu plus complexes) permettant de
garder l'arbre quilibr dans tous les cas. Parmi les techniques les plus connues, il y a : AVL-trees,
RedBlack-trees, B-trees, T-trees, ...etc. On verra comme complment ce chapitre quelques unes de
Hidouci W.K. / Les Arbres / Structures de donnes / ALSDD / ESI
ces techniques. Les B-trees qui gnralisent l'utilisation des arbres de recherche dans le stockage
efficace de donnes volumineuses en mmoire secondaire seront traits dans un autre module.
4) Implmentation des arbres binaire en contigu
On prsente ici, deux diffrentes manires de reprsenter des arbres binaires dans un espace de
stockage statique (tableau).
- Reprsentation standard
Elle ressemble celle utilise pour implmenter des listes linaires chanes dans un tableau.
Les nuds sont reprsents par les cases d'un tableau ayant une structure d'au moins trois champs :
(info : typeqlq, fg et fd : entier), on peut aussi rajouter un quatrime champs de type boolen pour
indiquer si la case est libre ou occupe :
type
Tcase = structure
info : typeqlq;
fg,fd : entier;
vide : bool
Fin
var
T : tableau[1..N] de Tcase;
Avec cette reprsentation, on peut facilement implmenter le modle standard des arbres binaire.
Si on veut en plus implmenter l'opration pere(n), on peut rajouter un autre champs de type entier
la structure Tcase.
- Reprsentation squentielle
Dans cette reprsentation, on limine les pointeurs entiers (fg,fd et ventuellement pere), en
associant chaque nud de l'arbre une position fixe prdfinie dans le tableau:
- la case d'indice 1 sera toujours rserve au nud racine de l'arbre,
- la case d'indice 2 sera toujours rserve au fg de la racine,
- la case d'indice 3 sera toujours rserve au fd de la racine,
- ....
En gnral, le fg de la case i se trouvera toujours l'indice 2i et le fd de la case i se trouvera
toujours l'indice 2i+1. Donc le pre de la case i sera toujours positionn la case i div 2.
On obtient ainsi une reprsentation compacte (qui consomme peu d'espace) mais pour laquelle, on
ne peut pas implmenter le modle standard des arbres binaire. C'est pour des utilisations un peu
particulires (voir ci-dessous : exemples d'applications).
5) Quelques exemples d'applications des arbres binaires
Les arbres binaires sont trs utiliss en programmation pour une multitude d'applications, on donne
ici un aperu sur quelques exemples d'utilisation.
10
/
2
+
5
Donner un algorithme rcursif pour valuer une expression sous la forme d'un arbre binaire.
- Acclrer l'accs par position dans une liste
On peut utiliser un genre particulier d'arbre de recherche binaire pour rendre l'accs par position
beaucoup plus rapide qu'un simple parcours squentiel.
Dans ce type d'arbre, les feuilles contiennent les valeurs d'une liste donne, alors que les nuds
internes forment un index de position : chaque nud interne contient un entier dsignant le nombre
de feuilles de son sous-arbre gauche.
Cette information sera utilise pour guider la recherche d'une position donne :
si la position cherche est infrieure ou gale l'information du nud interne on descend gauche,
sinon on descend droite et en retranche la position cherche l'information du nud.
5
5-2
3-2
5eme elt
11
On compare 3 avec l'information du nud qui indique 2 feuilles sa gauche, donc on descend
droite et on retranche 2.
Maintenant on recherche la position 1 et comme c'est infrieur ou gal l'information du nud
courant (1) on descend gauche.
Etant arriv au niveau d'une feuille avec la position cherche gale 1, on est donc positionn sur le
bon lment.
Trouver un moyen d'insrer et de supprimer par position dans une telle structure.
Il existe plusieurs manires de construire une telle structure partir d'un ensemble de valeurs (une
liste ou un tableau par exemple).
Essayer de trouver un algorithme rcursif qui permet de construire un arbre de ce type aussi
quilibr que possible partir d'un tableau de n lments.
- Codage de Huffman
Une autre utilisation des arbres binaires est de reprsenter des codes de longueurs variables pour les
symboles utiliss dans un message.
L'algorithme de Huffman gnre un code binaire de longueur variable pour chaque symbole d'un
message de sorte que les symboles ayant une haute frquence d'apparition (dans le message initial)
se voient attribuer des codes de longueurs rduites, alors que les symboles avec une faible frquence
d'apparition sont cods avec un nombre de bits plus important.
L'objectif de cet algorithme est de compresser des fichiers (messages).
1. Au dpart on calcule les probabilits d'apparition de chaque symbole (caractre). C'est le
nombre d'occurrence du caractre dans le message divis par la taille du message (en
nombre de caractres) Si ces probabilits sont dj connues, on peu viter cette tape.
2. A chaque caractre du message, on construit un nud (initialement isol) contenant ce
caractre.
3. Choisir les 2 nuds ayant la plus faible probabilit et non encore choisit
4. Crer un nouveau nud (un caractre fictif) en connectant les 2 nuds de l'tape prcdente
comme fils gauche et fils droit du nouveau nud. Associ ce nouveau nud la somme des
probabilits de ces 2 fils.
5. Rpter les deux dernires tapes (3 et 4) jusqu' ce qu'il n'y ait qu'un seul nud non encore
trait. C'est alors la racine de l'arbre de Huffman.
1
0
1
0
0
0
c
1
d
1
a
1
e
L'arbre ci-dessus est un exemple d'un codage longueur variable pouvant tre gnr par
Hidouci W.K. / Les Arbres / Structures de donnes / ALSDD / ESI
12
l'algorithme de Huffman.
Dans cet exemple, le code associ au symbole 'a' est 0101, celui associ 'h' est 01000 et celui
associ 'b' est 10.
Avec ce type de codage (reprsent par un arbre), la proprit du prfixe est toujours vrifie:
aucun code n'est le prfixe d'un autre et c'est ce qui permet de dcoder n'importe quelle chane
de bits sans ambigut.
Par exemple, la chane 1001110101011110 ne peut tre dcode que d'une seule manire, en la
parcourant de gauche droite, on est guid dans l'arbre pour atteindre les feuilles. A chaque fois
qu'on est sur une feuille, on aura dcod le caractre correspondant, on remonte la racine et
continue le parcours de la chane de bits. On obtient alors le message dcod : bcbbbdb
- File de priorit
Une file de priorit est un ensemble o on peut enfiler des valeurs associes des priorits (des
poids) et quand on dfile un lment, on doit retirer de l'ensemble la valeur ayant la plus forte
priorit.
On peut implmenter de manire efficace ce type d'ensemble l'aide d'un arbre binaire comme suit:
L'arbre est construit niveau par niveau et chaque niveau est rempli de gauche droite.
Les nuds de l'arbre renferment les lments de la file de priorit tout en respectant la proprit
suivante : pour tout nud interne p, priorit(p) priorit(de ses fils)
Voici un exemple :
25
18
15
8
3
10
17
12
2
14
11
Quand on enfile un nouvel lment, on le rajoute temporairement la premire position libre (c-a-d
ajouter une nouvelle feuille dans le dernier niveau et en partant de gauche droite), ensuite on le
fait remonter par une srie de permutations avec le pre, jusqu' ce que sa proprit soit celle de
son pre.
Par exemple, si on enfile un lment de priorit 20, on commence par l'insrer comme fils gauche
de 6 (c'est la premire position libre dans le dernier niveau).
13
25
18
15
8
3
10
17
12
2
14
11
20
Puis en permute l'lment 20 avec son pre (car 20 > 6), et on continue les permutations avec son
nouveau pre (18) et on s'arrte ce niveau car 20 25.
25
20
15
8
3
10
18
17
12
2
14
11
Pour dfiler un lment (le plus prioritaire de l'ensemble), il suffit de retirer la racine de l'arbre.
Remplacer temporairement la racine par la feuille la plus droite.
Puis faire descendre l'lment de la racine temporaire par une srie de permutations avec le plus
grand des fils, jusqu' ce que sa priorit soit celles de ses fils.
Dans l'exemple prcdent, quand on dfile l'lment 25, on le remplace temporairement par la
feuille la plus droite (6) que l'on supprime :
6
20
15
8
3
10
18
17
12
2
14
11
15
8
3
10
17
12
2
14
11
Pour implmenter ces oprations de manire efficace, on utilise la reprsentation squentielle des
Hidouci W.K. / Les Arbres / Structures de donnes / ALSDD / ESI
14
arbres binaire.
6) Arbres m-aire
Un arbre m-aire d'ordre d est un arbre o chaque nud peut avoir un nombre de fils compris entre 0
et d. Si l'ordre n'est pas connu, on dit alors simplement un arbre m-aire. Dans ce cas le nombre de
fils est thoriquement illimit.
Pour crire des algorithmes sur ce type d'arbres, on dfinit un modle form par les oprations
suivantes :
Creernud( v ) : ptr
Librernud( p )
info( p ) : typeqlq
Fils( i,p ) : ptr
Aff-info( p,v )
Aff-Fils( i,p,q )
degr( p ) : entier
Aff-degr( p,x )
Dans le cas d'un arbre m-aire, o l'ordre n'est pas connu, l'opration Aff-degr(...) n'est pas
implmente. De plus, il n'existe pas de fils NIL dans un tel arbre.
- Implmentation dynamique
Si l'ordre de l'arbre n'est pas connu, l'implmentation standard d'un arbre m-aire en dynamique
consiste allouer des nuds ayant 3 champs : l'information, le premier fils et le frre droit.
a
b
g
i
Si l'ordre est connu, il plus simple de rserver un tableau de d pointeurs pour reprsenter les fils.
- Implmentation statique
C'est le mme principe qui est utilis dans l'implmentation dynamique sauf que les nuds sont
localiss l'intrieur d'un tableau.
Donc soit un tableau 3 champs principaux (info, premier_fils, et frre_droit) dans le cas o l'ordre
est inconnu, soit rserv un tableau de d entier l'intrieur de chaque case du tableau principal si
l'ordre est connu.
15
16