Sunteți pe pagina 1din 17

option informatique

Chapitre 1

Arbres binaires

1.

Introduction

Dans son acceptation la plus gnrale, un arbre est un graphe connexe acyclique enracin 1 : tous les sommets,
lexception de la racine, ont un unique parent.
1
2
5

6
9

10

11

12

Figure 1 Un exemple darbre enracin en 1.


Si une arte mne du sommet i au sommet j, on dit que i est le pre de j, et en consquence que j est le fils de i.
Par exemple, le sommet 3 est le pre de 7, le sommet 6 est le fils de 2.
Il est dusage de dessiner un arbre en plaant un pre au dessus de ses fils, si bien que lon peut sans ambigit
reprsenter les artes par des traits simples la place des flches, ce que lon fera par la suite 2 .
Dans ce contexte, il est frquent de parler de nud au lieu de sommet. Un nud qui na pas de fils est appel
une feuille (ou nud externe), les autres sont appels des nuds internes. Dans lexemple ci-dessus, les feuilles
sont les sommets 5, 7, 9, 10, 11, et 12 et les nuds internes les sommets 1, 2, 3, 4, 6, et 8.
Enfin, on notera que chaque nud est la racine dun arbre constitu de lui-mme et de lensemble de ses
descendants ; on parle alors de sous-arbre de larbre initial. Par exemple, les sommets 2, 5, 6, 9 et 10 constituent
un sous-arbre de larbre reprsent ci-dessus.

1.1

Dfinition formelle dun arbre binaire

On appelle arit dun nud le nombre de branches qui en partent 3 . Dans la suite de notre cours, nous nous
intresserons plus particulirement aux arbres binaires, cest dire ceux dont chaque nud a au plus deux fils.
Pour ne pas avoir distinguer les nuds suivant leur arit, il est pratique dajouter lensemble des arbres
binaires un arbre particulier appel larbre vide. Ceci conduit adopter la dfinition qui suit.
Un ensemble E tant donn, on dfinit par induction les arbres binaires tiquets par E en convenant que :
nil est un arbre binaire sur E appel larbre vide ;
si x E et si Fg et Fd sont deux arbres binaires tiquets par E, alors A = (Fg , x, Fd ) est un arbre binaire
tiquet par E.
x est ltiquette de la racine de A ; quant Fg et Fd , ils sont appels respectivement le sous-arbre gauche et le
sous-arbre droit de larbre binaire A.
De manire usuelle, on convient de ne pas faire figurer larbre vide dans les reprsentations graphiques
des arbres binaires (voir la figure 2). Ainsi, suivant la reprsentation choisie les feuilles pourront dsigner
exclusivement larbre vide (et dans ce cas tous les nuds seront darit gale 2) ou alors les nuds dont les
deux fils sont vides (dans ce cas larit dun nud pourra tre gale 0, 1 ou 2). Cest cette seconde convention
qui sera utilise dans la suite de ce cours.
1. La dfinition prcise de ces termes sera donne dans le chapitre suivant.
2. Plus prcisment, nous dmontrerons quune fois la racine choisie, il existe une unique orientation des artes qui permette de se
dplacer de la racine vers chacun des autres sommets.
3. son degr sortant, pour employer le vocabulaire des graphes.

Jean-Pierre Becirspahic

1.2

option informatique

1
nil

2
nil

nil

1
0

nil
nil

nil

0
2

1
0

nil

2
2

nil

Figure 2 Trois reprsentations du mme arbre binaire.


Mise en uvre pratique
La dfinition formelle que nous avons adopte peut se rsumer :
Arbre = nil + Arbre nud Arbre
et conduit la dfinition Caml suivante :
type a arbre = Nil | Noeud of (a arbre * a * a arbre) ;;

1.2

Fonctions inductives

Preuve par induction structurelle


La plupart des rsultats qui concernent les arbres binaires se prouvent par induction structurelle, cest--dire en
utilisant le rsultat suivant :
Thorme. Soit R une assertion dfinie sur lensemble A des arbres tiquets par E. On suppose que :
(i) R (nil) est vraie ;


(ii) x E, (Fg , Fd ) A 2 , limplication R (Fg ) et R (Fd ) = R (Fg , x, Fd ) est vraie ;
Alors la proprit R (A) est vraie pour tout arbre A de A .
De mme, de nombreuses fonctions f : A F se dfinissent par la donne dun lment a F, dune fonction
: F E F F et les relations :
f (nil) = a ;
x E, (Fg , Fd ) A 2 , f (Fg , x, Fd ) = (f (Fg ), x, f (Fd )).
Dfinition. La taille |A| dun arbre A est dfinie inductivement par les relations :
|nil| = 0 ;
Si A = (Fg , x, Fd ) alors |A| = 1 + |Fg | + |Fd |.
La hauteur h(A) dun arbre A se dfinit inductivement par les relations :
h(nil) = 1 ;
Si A = (Fg , x, Fd ) alors h(A) = 1 + max(h(Fg ), h(Fd )).
Avec ces conventions, |A| est le nombre de nuds dun arbre et h(A) la longueur maximale du chemin reliant la
racine une feuille, autrement dit la profondeur maximale dun nud.
La dfinition Caml de ces fonctions est immdiate :
let rec taille = function
| Nil
> 0
| Noeud (fg, _, fd) > 1 + taille fg + taille fd ;;
let rec hauteur = function
| Nil
> 1
| Noeud (fg, _, fd) > 1 + max (hauteur fg) (hauteur fd) ;;

Arbres binaires

1.3

Autre exemple, pour calculer le nombre de feuilles dun arbre binaire on utilise la fonction :
let
|
|
|

rec nb_feuilles = function


Nil
> 0
Noeud (Nil, _, Nil) > 1
Noeud (fg, _, fd)
> nb_feuilles fg + nb_feuilles fd ;;

Thorme. Soit A un arbre binaire. Alors h(A) + 1 6 |A| 6 2h(A)+1 1.


Preuve. On raisonne par induction structurelle.
Si A = nil, |A| = 0 et h(A) = 1 et le rsultat annonc est bien vrifi.
Si A = (Fg , x, Fd ), supposons le rsultat acquis pour Fg et Fd . On a :
|A| = 1 + |Fg | + |Fd | > 1 + h(Fg ) + 1 + h(Fd ) + 1 > 2 + max(h(Fg ), h(Fd )) = 1 + h(A)
et

1.3

|A| = 1 + |Fg | + |Fd | 6 2h(Fg )+1 + 2h(Fd )+1 1 6 2 2max(h(Fg ),h(Fd ))+1 1 = 2h(A)+1 1

Arbres binaires quilibrs

Revenons sur le rsultat nonc dans le dernier thorme, quon peut aussi crire : si A est un arbre binaire alors
log(|A| + 1) 1 6 h(A) 6 |A| 1. Dans la suite de ce cours nous aurons plusieurs reprises intrt utiliser des
arbres qui, pour une taille donne, ont une hauteur minimale, autrement dit pour lesquels h(A) = O(log(|A|)).
De tels arbres seront dits quilibrs.
tudions tout dabord le cas optimal h(A) = log(|A| + 1) 1, correspondant aux arbres binaires complets. Daprs
la preuve du thorme prcdent, pour que A = (Fg , x, Fd ) soit complet il faut et il suffit que Fg et Fd soient
complets et de mme hauteur. Il est ds lors facile dtablir par induction quun arbre binaire est complet si et
seulement si toutes ses feuilles sont la mme profondeur.
0
1

1
4

2
0

8
2

0
1

Figure 3 Un exemple darbre binaire complet : |A| = 15 et h(A) = 3.


Cependant, la plupart des arbres binaires que lon rencontre dans la pratique ne sont pas complets, cette notion
tant trop restrictive ; cest pourquoi on privilgie certaines catgories darbres qui garantissent lquilibrage :
arbres rouge-noir 4 , arbres AVL, etc.
Par exemple, la catgorie des arbres AVL introduit la notion de dsquilibre : le dsquilibre dun arbre
A = (Fg , x, Fd ) est gal lentier h(Fg ) h(Fd ). On adopte alors la dfinition :
Dfinition. Un arbre binaire A est un arbre AVL 5 lorsquil est vide ou gal (Fg , x, Fd ) avec :
Fg et Fd sont des arbres AVL ;
le dsquilibre de A est gal 1, 0 ou 1.
Autrement dit, un arbre AVL est un arbre dans lequel le dsquilibre de chaque sous-arbre est gal 1, 0 ou 1.
Thorme. Tout arbre AVL est quilibr.

4. Voir lexercice 5 ce sujet.


5. Daprs le nom de leurs inventeurs Adelson-Velsky et Landis.

Jean-Pierre Becirspahic

1.4

option informatique

0
0

1
0

0
0

1
0

1
0

Figure 4 Larbre de gauche est un AVL, pas celui de droite 6 .


Preuve. On considre la suite de Fibonacci dfinie par f0 = 0, f1 = 1 et la relation fn+2 = fn+1 + fn . Nous allons
montrer par induction structurelle que tout arbre AVL A de hauteur h contient au moins fh nuds.
Si A = nil alors |A| = 0 = f0 .
Si A = (Fg , x, Fd ), lun des deux sous-arbres Fg ou Fd est de hauteur h 1 donc contient au moins fh1 nuds,
lautre est au moins de hauteur h 2 donc contient au moins fh2 nuds. On en dduit que A contient au
moins fh1 + fh2 + 1 = fh + 1 nuds.

1+ 5
Sachant que fh = (h ) avec =
on en dduit : h(A) = O(|A|), soit h(A) = O(log |A|).
2

2.

Arbres binaires de recherche

Un arbre binaire de recherche (en abrg : ABR) permet limplmentation sous forme darbre binaire de certaines
structures de donnes stockant des lments forms dune cl et dune valeur, tels les dictionnaires 7 . Nous
allons donc considrer un ensemble ordonn de cls C ainsi quun ensemble de valeurs V, et utiliser des arbres
binaires tiquets par E = C V.
Les arbre binaire de recherche supportent nombre doprations quon utilise dans les structures de donnes, en
particulier :
la recherche dun valeur associe une cl donne ;
la recherche de la valeur associe la cl maximale (ou minimale) ;
la recherche du successeur dune cl c, cest dire la valeur associe la plus petite des cls strictement
suprieures c ;
la recherche du prdcesseur dune cl ;
et bien sr linsertion ou la suppression dun nouveau couple cl/valeur.
15
6
7

4
2

19

5
3

17
13

20

18

Figure 5 Un exemple darbre binaire de recherche (seules les cls ont t reprsentes)

Dfinition. un arbre binaire A est un arbre binaire de recherche sil est vide ou gal (Fg , (c, v), Fd ) o :
Fg et Fd sont des arbres binaires de recherche ;
toute cl de Fg est infrieure (ou gale 8 ) c ;
toute cl de Fd est suprieure (ou gale) c.
6. Les arbres sont tiquets par leur dsquilibre.
7. Voir le cours de premire anne.
8. Il serait prfrable dimposer aux cls prsentes dtre deux deux distinctes, mais cela nest pas toujours vrifi dans la pratique.

Arbres binaires

1.5

Autrement dit, A est un arbre binaire de recherche lorsque tout nud de A est associ une cl suprieure ou
gale toute cl de son fils gauche, et infrieure ou gale toute cl de son fils droit.
Dans la suite du cours, on utilisera le type :
type (a, b) data = {Key : a; Value : b} ;;

et les arbres binaires de recherche seront reprsents par le type ( a, b) data arbre.

2.1

Parcours infixe dun arbre binaire de recherche

La proprit des arbres binaires de recherche permet dafficher toutes les valeurs de larbre par ordre croissant
de cl laide dun parcours infixe. Rappelons rapidement le principe de lexploration en profondeur dun arbre
(Fg , x, Fd ) : chaque sous-arbre est explor dans son entier avant dexplorer le second sous-arbre. Le parcours
infixe consiste parcourir larbre dans lordre : Fg x Fd .
Si traitement est une fonction de type b > unit , le parcours infixe dun arbre binaire de recherche prendra la
forme suivante :
let rec parcours_infixe = function
| Nil
> ()
| Noeud (fg, x, fd) > parcours_infixe fg ;
traitement x.Value ;
parcours_infixe fd ;;

lvidence, le cot temporel de ce parcours est un (n) lorsque n = |A|.


Thorme. Lors du parcours infixe dun arbre binaire de recherche, les cls sont parcourues par ordre croissant.
Preuve. On procde par induction :
si A = nil, il ny a rien prouver ;
si A = (Fg , x, Fd ), on suppose que les parcours infixes de Fg et de Fd se font par ordre de cls croissantes.
Sachant que toute cl de Fg est infrieure la cl de x et toute cl de Fd suprieure cette dernire, le
parcours Fg x Fd est bien effectu par ordre croissant de cl.

2.2

Requtes dans un arbre binaire de recherche

Recherche dune cl
Une des oprations les plus courantes dans un arbre binaire de recherche A = (Fg , (c, v), Fd ) est la recherche
dune valeur associe une cl particulire k. La dmarche est vidente :
si k = c, retourner v ;
si k < c, rechercher k dans Fg ;
si k > c, rechercher k dans Fd .
Dans le cas o les cls ne sont pas toutes distinctes on retournera la valeur associe la premire cl gale k
rencontre.
let
|
|
|
|

rec recherche k = function


Nil
Noeud (_, x, _) when k = x.Key
Noeud (fg, x, _) when k < x.Key
Noeud (_, _, fd)

>
>
>
>

raise Not_found
x.Value
recherche k fg
recherche k fd ;;

Par exemple, la recherche de la valeur associe la cl k = 13 dans larbre de la figure 5 conduit suivre le
chemin : 15 6 7 13 partir de la racine.
Jean-Pierre Becirspahic

1.6

option informatique

Recherche de la cl minimale / maximale


La recherche de la valeur associe la cl minimale se poursuit dans le fils gauche tant que ce dernier nest pas
vide :
let
|
|
|

rec minimum = function


Nil
> raise Not_found
Noeud (Nil, x, _) > x.Value
Noeud (fg, _, _) > minimum fg ;;

La fonction retournant la valeur associe la cl maximale est symtrique :


let
|
|
|

rec maximum = function


Nil
> raise Not_found
Noeud (_, x, Nil) > x.Value
Noeud (_, _, fd) > maximum fd ;;

Dans lexemple de la figure 5 on obtient la cl minimale 2 en suivant les fils gauches partir de la racine, et la
cl maximale 20 en suivant les fils droits.
Recherche du prdcesseur / successeur
k C tant donn, il sagit cette fois de retourner la valeur associe la plus grande des cls c contenues dans
larbre et vrifiant : c < k (respectivement c > k).
let
|
|
|

rec predecesseur k = function


Nil
> raise Not_found
Noeud (fg, x, _) when x.Key >= k > predecesseur k fg
Noeud (_, x, fd)
> try predecesseur k fd
with Not_found > x.Value ;;

let
|
|
|

rec successeur k = function


Nil
> raise Not_found
Noeud (_, x, fd) when x.Key <= k > successeur k fd
Noeud (fg, x, _)
> try successeur k fg
with Not_found > x.Value ;;

Par exemple, le successeur de 13 dans lABR reprsent figure 5 est la racine 15 puisquil ny a pas de successeur
possible dans le fils gauche.

Complexit temporelle
Toutes ces fonctions ont lvidence un cot temporel en O(h(A)), ce qui explique tout lintrt quil peut y
avoir ce que larbre binaire de recherche soit quilibr : dans un arbre binaire quelconque dordre n = |A|, on
peut affirmer que le cot dune requte est un O(n) ; dans le cas dun arbre de recherche quilibr, on peut
assurer un cot en O(log n).

2.3

Insertion et suppression

Insertion et suppression dans un arbre binaire de recherche quelconque


Il existe deux techniques dinsertion dune nouvelle cl dans un arbre binaire de recherche : au niveau des
feuilles ou au niveau de la racine.
La premire est trs semblable celle employe pour rechercher un lment. Pour insrer le couple (k, u) C V
dans larbre A on procde ainsi :
si A = nil, on retourne larbre (nil, (k, u), nil) ;
si A = (Fg , (c, v), Fd ) alors :
si c = k on remplace 9 le couple (c, v) par (k, u) et on insre (c, v) dans Fg ou Fd ;
si c > k on insre (k, u) dans Fg ;
si c < k on insre (k, u) dans Fd .
9. Lorsquon autorise la prsence de cls identiques dans un ABR, on souhaite que la fonction recherche renvoie la valeur associe la
cl la plus rcemment introduite, autrement dit que celle-ci se trouve la profondeur minimale.

Arbres binaires

let
|
|
|
|

1.7

rec insere_feuille y = function


Nil
Noeud (fg, x, fd) when x.Key = y.Key
Noeud (fg, x, fd) when x.Key > y.Key
Noeud (fg, x, fd)

>
>
>
>

Noeud
Noeud
Noeud
Noeud

(Nil, y, Nil)
(fg, y, insere_feuille x fd)
(insere_feuille y fg, x, fd)
(fg, x, insere_feuille y fd) ;;

Lautre possibilit consiste insrer le nouvel lment la racine puis partitionner larbre de manire placer
tous les lments infrieurs la nouvelle cl dans le fils gauche et les autres dans le fils droit :
let insere_racine y a =
let rec partition = function
| Nil
> Nil, Nil
| Noeud (fg, x, fd) when x.Key < y.Key > let a1, a2 = partition fd in
Noeud (fg, x, a1), a2
| Noeud (fg, x, fd)
> let a1, a2 = partition fg in
a1, Noeud (a2, x, fd)
in let fg, fd = partition a in Noeud (fg, y, fd) ;;

On trouvera figure 6 un exemple dinsertion dune cl par ces deux techniques dans lABR reprsent figure 5.
15

19
7

4
2

17
13

6
20

18

4
2

5
3

15
13
9

19
17 20
18

8
Figure 6 Insertion au niveau des feuilles et au niveau de la racine dune cl de valeur 8.
Ces fonctions dinsertion ont toutes deux un cot en O(h(A)).
La suppression dune cl k dans un arbre binaire de recherche consiste supprimer le couple (k, v) situ la
profondeur minimale dans larbre A = (Fg , (c, v), Fd ). On procde ainsi :
si k < c, on supprime un lment de cl k dans Fg ;
si k > c, on supprime un lment de cl k dans Fd ;
si k = c, alors :
si Fg = nil on renvoie Fd ;
si Fd = nil on renvoie Fg ;
sinon, on supprime de Fd un lment m de cl minimale pour obtenir Fd0 et on retourne (Fg , m, Fd0 ).
Nous aurons besoin dune fonction qui prend en argument un arbre A et retourne le couple (m, A0 ) form dun
lment m de cl minimale et de larbre A0 = A \ {m} :
let
|
|
|

rec supprime_min =
Nil
Noeud (Nil, m, fd)
Noeud (fg, x, fd)

function
> failwith "supprime_min"
> m, fd
> let m, f = supprime_min fg in m, Noeud (f, x, fd) ;;

La suppression dune cl k se ralise alors ainsi :


let rec supprime k = function
| Nil
> raise Not_found
| Noeud (fg, x, fd) when x.Key < k > Noeud (fg, x, supprime k fd)
| Noeud (fg, x, fd) when x.Key > k > Noeud (supprime k fg, x, fd)
| Noeud (Nil, x, fd) > fd
| Noeud (fg, x, Nil) > fg
| Noeud (fg, x, fd) > let m, f = supprime_min fd in Noeud (fg, m, f) ;;

Jean-Pierre Becirspahic

1.8

option informatique

17
6

19
7

4
2

18

20

13

Figure 7 Suppression de la cl de valeur 15 dans lABR de la figure 5


La fonction de suppression a elle aussi un cot temporel en O(h(A)) puisque chaque appel rcursif seffectue
sur un arbre de hauteur infrieur au prcdent.

Le problme du dsquilibre
Nous avons vu que toutes les fonctions de requtes, dinsertion et de suppression dans un arbre de recherche
ont un cot temporel en O(h(A)), autrement dit, en posant n = |A| :
un cot linaire O(n) dans le cas dun arbre de recherche quelconque ;
un cot logarithmique O(log n) dans le cas dun arbre de recherche maintenu quilibr.
Malheureusement, les fonctions dinsertion et de suppression que nous avons crites peuvent conduire des
arbres trs dsquilibrs, par exemple des arbres peignes dans le cas o les cls sont insres par ordre croissant
ou dcroissant.
1

5
2

4
3

3
2

4
5

Figure 8 Insertion des cls 1, 2, 3, 4, 5 au niveau des feuilles ou au niveau de la racine.


Cependant, on peut dmontrer (mais cest difficile) que le comportement du cas moyen est plus proche du cas
optimal que du cas le plus dfavorable. Plus prcisment, si un arbre binaire de recherche est cr en insrant n
cls distinctes au niveau des feuilles dans un ordre alatoire (chacune des n! permutations tant quiprobable),
il existe une constante c telle que la hauteur moyenne de ces n! arbres soit quivalente c log n.
Par exemple, les six arbres que lon peut obtenir en insrant dans un ordre arbitraire les trois entiers 1, 2 et 3
sont les suivants :
123

312

231

213

3
2

1
3

1
2

132

321

1
3

3
3

2
1

On peut constater que cette manire de faire diffre de celle consistant supposer que chaque arbre binaire de
recherche n nuds est quiprobable : larbre binaire complet a la probabilit 1/3 dapparaitre, contre 1/6 pour
les quatre autres 10 .

10. La hauteur moyenne dun arbre binaire de recherche de taille n sils sont tous quiprobables est quivalente 2 n.

Arbres binaires

1.9

Insertion et suppression dans un arbre binaire quilibr


Il est nanmoins possible de garantir une complexit dans le pire des cas en O(log n) condition de maintenir
en place une structure darbre qui garantisse lquilibrage : arbres AVL, arbres rouge-noir, etc. (lutilisation
darbres AVL pour reprsenter des arbres binaires de recherche est tudie dans lexercice 9).

2.4

Arbres binaires de recherche et dictionnaires

Dans le cours de premire anne a t tudie la notion de table dassociation, ou dictionnaire : si C dsigne
lensemble des cls et V lensemble des valeurs, une table dassociation T est un sous-ensemble de C V tel que
pour toute cl c C il existe au plus un lment v V tel que (c, v) T.
Une table dassociation supporte en gnral les oprations suivantes :
ajout dune nouvelle paire (c, v) C V dans T ;
suppression dune paire (c, v) de T ;
lecture de la valeur associe une cl dans T.
Il a t montr quune table de hachage permet la ralisation dune structure imprative de dictionnaire, avec les
cots suivants :
pire des cas
lecture
ajout
(n)
(n)

en moyenne
lecture
ajout
(1)
(1)

La structure darbre binaire de recherche permet la ralisation dune structure persistante de dictionnaire, avec
les cots :
pire des cas
lecture
ajout
(log n) (log n)

en moyenne
lecture
ajout
(log n) (log n)

condition de maintenir quilibrs les ABR.

3.

Tas binaire

3.1

Tas-min et tas-max

Un arbre binaire est dit parfait lorsque tous les niveaux hirarchiques sont remplis sauf ventuellement le
dernier, partiellement rempli de la gauche vers la droite.
16
10

14
8
2

7
4

Figure 9 Un exemple de tas-max.


Si A est un arbre parfait, alors 1 + 2 + + 2h(A)1 < |A| 6 1 + 2 + + 2h(A) donc 2h(A) 6 |A| < 2h(A)+1 . La hauteur
dun arbre parfait n nuds est gale blog nc ; cest un arbre quilibr.
On appelle tas-max un arbre parfait tiquet par un ensemble ordonn E tel que ltiquette de chaque nud
autre que la racine soit infrieure ou gale ltiquette de son pre.
Bien entendu, un tas-min possde la proprit oppose : ltiquette de chaque nud autre que la racine est
suprieure ou gale ltiquette de son pre.
Jean-Pierre Becirspahic

1.10

option informatique

Implmentation dun tas


Comme tout arbre binaire, un tas peut tre reprsent par le type a arbre, mais une autre reprsentation est
possible en utilisant un vecteur de type a vect . Rappelons que la numrotation Sosa-Stradonitz des nuds
dun arbre binaire se dfinit ainsi :
la racine porte le numro 1 ;
si un nud porte le numro k, son fils gauche porte le numro 2k et son fils droit le numro 2k + 1.
jk k
De ceci il rsulte immdiatement que le pre dun nud de numro k porte le numro
.
2
Il est donc possible dtablir une correspondance entre lindice k > 1 dun tableau et la numrotation dun
nud. Dans le cas dun arbre binaire quelconque, cette reprsentation ne prsente en gnral pas dintrt car
le nombre de cases inutilises peut tre trs important (dans le cas extrme dun arbre peigne gauche, seules les
cases correspondant aux puissances de 2 sont utilises, ce qui ncessiterait un cot spatial exponentiel pour le
reprsenter). En revanche, pour un arbre parfait, seules les cases numrotes entre 1 et n sont utilises pour
reprsenter un arbre de taille n.
16 14 10 8

Figure 10 Une reprsentation tabulaire du tas-max de la figure 9.


On notera que les tableaux Caml sont indexs partir du rang 0, ce qui nous laisse deux possibilits : ou bien ne
pas utiliser la case dindice 0 et conserver la numrotation prsente ci-dessus, ou bien dcaler la numrotation
dun cran. Cest ce que nous allons faire dans la suite de ce chapitre, en adoptant dsormais la convention
suivante :
la racine est stocke dans la case dindice 0 ;
si un nud est stock dans la case dindice k, son fils gauche est stock dans la case dindice 2k + 1 et son
fils droit dans la case dindice 2k + 2 ;
jk 1k
si un fils est stock dans le case dindice k, son pre est stock dans la case dindice
.
2

3.2

Oprations usuelles sur les tas

Dans ce qui suit, nous ne prendrons en compte que des tas-max, mais il va de soit que toutes les fonctions que
nous crirons sadaptent sans difficult au cas des tas-min.

Prservation de la structure de tas


Une des oprations les plus frquentes sur les tas consiste reconstituer la structure de tas aprs quun lment
ait t modifi. Si la nouvelle valeur de cet lment est suprieure la prcdente, il se peut que cet lment
doive monter dans larbre pour reconstituer un tas ; dans le cas contraire, il se peut que cet lment ait
descendre dans larbre.
16

16
10

14
18
2

7
4

3
3

10

8
2

7
4

Figure 11 gauche, llment entour doit monter dans le tas-max ; droite il doit descendre.
La monte est plus simple : il suffit de permuter llment modifi avec son pre tant que la structure de tas
nest pas reconstitue :
let swap t i j =
let x = t.(i) in t.(i) < t.(j) ; t.(j) < x ;;

Arbres binaires

1.11

let monte t k =
let rec aux = function
| 0 > ()
| i > let j = (i1)/2 in
if t.(i) > t.(j) then (swap t i j ; aux j)
in aux k ;;

Pour la descente, cest un peu plus dlicat : il faut permuter llment modifi avec le plus grand de ses fils, sil
en existe. On introduit un paramtre supplmentaire qui indique lindice de la premire case non utilise dans
la reprsentation du tas (si le tableau t est plein, on aura donc n = vect_length t) 11 .
Trois cas sont possibles : si 2i + 2 < n, ti possde deux fils t2i+1 et t2i+2 ; si n = 2i + 2, ti possde un seul fils t2i+1 ;
si 2i + 1 > n ti ne possde pas de fils.
let descend t n k =
let rec aux = function
| i when 2*i+2 > n > ()
| i > let j = if 2*i+2 = n || t.(2*i+1) > t.(2*i+2) then 2*i+1 else 2*i+2 in
if t.(i) < t.(j) then (swap t i j ; aux j)
in aux k ;;

Le temps dexcution de chacune des ces deux fonctions dans un tas T est un O(h(T)) donc un O(log n), lentier
n dsignant la taille du tas.

construction dun tas


Il y a deux faons de convertir un tableau t en un tas-max. La premire consiste maintenir linvariant : t[0..k]
est un tas-max en faisant remonter llment tk dans le tas situ sa gauche laide de la fonction monte :
12
12 8

tas

4 11 10
7

k
2

6
5

Figure 12 Une tape de la construction dun tas par remonte des nuds.
let cree_tas t =
for k = 1 to vect_length t 1 do monte t k done ;;

Dans le pire des cas, chaque remonte aboutit la racine (cest le cas par exemple lorsque le tableau est
initialement tri par ordre croissant). Dans ce cas, le nombre de permutations effectues est gal la somme des
profondeurs de chacun des nuds lexception de la racine. Si on note p = blog nc la hauteur du tas, le nombre
de permutations est donc gal :
p1
X

k2k + p(n 2p + 1) = (n + 1)p 2p+1 + 2 = (n log n).

k=1

On peut faire mieux en observant (voir lexercice 11) que la deuxime moiti du tableau t correspond aux
feuilles de larbre et que chacune de ces feuilles est un tas un lment. Il suffit donc de faire descendre
llment tk pour unir peu peu ces diffrents tas, de manire prserver linvariant : chaque nud de
t[k..n 1] est la racine dun tas-max .
let cree_tas t =
let n = vect_length t in
for k = n/21 downto 0 do descend t n k done ;;

11. Lintrt de ce paramtre napparaitra que dans la section 3.3.

Jean-Pierre Becirspahic

1.12

option informatique

2 12 3 11 9

1 10 6

11

plusieurs tas

1 10 6

7
8

Figure 13 Une tape de la construction dun tas par descente des pres.
Dans le pire des cas, chaque descente aboutit au descendant le plus loign et ralise donc h changes, o h est
la hauteur de larbre dont il est la racine. Par ailleurs, le nombre de nuds ayant la hauteur h est major par
l n m
(voir lexercice 11) donc le nombre total dchanges est major par :
2h+1
p
p
X
X
l n m
p(p + 1)
h
= (n)
h6
+n
h+1
h+1
2
2
2
h=1

car p = blog nc et la srie

h=1

X h
converge.
2h+1

Cette deuxime mthode permet donc de construire un tas-max en temps linaire.

3.3

Tri par tas

La notion de tas conduit naturellement un algorithme de tri appel le tri par tas (heap sort en anglais) : pour
trier un tableau t, on commence par le transformer en tas-max laide de la fonction cree_tas. lissue de
cette premire tape, llment maximal se trouve la racine t0 et on peut le placer dans sa position finale en le
permutant avec tn1 . Il faut ensuite reformer le tas entre les indices 0 et n 2 en faisant descendre tn1 laide
de la fonction descend. Il reste ritrer ce processus pour le tas-max de taille n 1, jusqu arriver un tas de
taille 1.
11
11 8 10 7

3 12 13 14 15 16 17

tas

10

partie trie
5

4
6

Figure 14 Un tableau en cours de tri.


let tri_tas t =
cree_tas t ;
for k = vect_length t 1 downto 1 do
swap t 0 k ;
descend t k 0
done ;;

La validit de cette dmarche est assure par linvariant suivant : au dbut de chaque itration le sous-tableau
t[0 . . . k] est un tas contenant les k + 1 plus petits lments de t et t[k + 1 . . . n 1] un tableau tri contenant les
n k 1 plus grands lments de t .
Complexit temporelle
Puisque la fonction cree_tas a un cot temporel en O(n) et que chacune des appels la fonction descend un
cot en O(log n), le cot total de cette mthode de tri est un O(n log n).

3.4

Files de priorit

Une des applications des tas est la mise en uvre des files de priorits, qui permettent de grer un ensemble V
de valeurs associes chacune une priorit, lment dun ensemble totalement ordonn.
Par exemple, une file de priorit permet de planifier les tches dun ordinateur : la file gre les travaux en
attente, avec leurs priorits relatives. Lorsquune tche est termine ou interrompue, lordinateur excute la
tche de plus forte priorit parmi les travaux en attente.

Arbres binaires

1.13

Une file de priorit supporte en gnral les oprations suivantes :


cration dune file de priorit vide ;
insertion dun couple (v, p) o v est la valeur de la donne et p sa priorit ;
retrait de la valeur v associe la priorit maximale p ;
accroissement de la priorit associe une valeur donne.
Nous dfinissons donc le type :
type (a, b) data = {Priority: a; Value: b} ;;

Puisque le tas est reprsent par un vecteur, il est ncessaire de choisir la taille maximale du tas au moment
de sa cration, et puisquil est destin voluer en taille, il faut garder trace de lindice de la premire case
disponible. On utilise donc le type suivant :
type a tas = {mutable N: int; Tbl: a vect} ;;

Le champ mutable N dsigne lindice de la premire case disponible, ce qui permettra de faire grandir le tas.
16 14 10 8

1
N

Figure 15 Une reprsentation dynamique du tas-max de la figure 9.


On dfinit deux exceptions :
exception Empty ;;
exception Full ;;

et on modifie lgrement les dfinitions des fonctions monte et descend pour tenir compte du type de donnes
utilis (il sagit maintenant de comparer les priorits des lments du tableau) :
let monte t k =
let rec aux = function
| 0 > ()
| i > let j = (i1)/2 in
if t.(i).Priority > t.(j).Priority then (swap t i j ; aux j)
in aux k ;;
let descend t n k =
let rec aux = function
| i when 2*i+1 >= n > ()
| i > let j = if 2*i+2 = n || t.(2*i+1).Priority > t.(2*i+2).Priority
then 2*i+1 else 2*i+2 in
if t.(i).Priority < t.(j).Priority then (swap t i j ; aux j)
in aux k ;;

La cration dune file de priorit vide ncessite de fixer au dpart la taille maximale du tas et dattribuer une
valeur arbitraire aux lments du tableau pour fixer le type :
let cree_file n (p, v) = {N = 0 ; Tbl = make_vect n {Priority = p; Value = v}} ;;

Linsertion consiste placer le nouvel lment en dernire position puis le faire remonter :
let ajout (p, v) f =
if f.N = vect_length f.Tbl then raise Full ;
f.Tbl.(f.N) < {Priority = p; Value = v} ;
monte f.Tbl f.N ;
f.N < f.N + 1 ;;

Pour le retrait de la valeur de priorit maximale, on permute le dernier lment du tas avec la racine puis on le
fait descendre :
Jean-Pierre Becirspahic

1.14

option informatique

let retrait f =
if f.N = 0 then raise Empty ;
let v = f.Tbl.(0).Value in
f.N < f.N 1 ;
f.Tbl.(0) < f.Tbl.(f.N) ;
descend f.Tbl f.N 0 ;
v ;;

Enfin, aprs avoir accru la valeur dune cl, il suffit de la faire remonter pour reformer le tas :
let incr f k c =
if c < f.Tbl.(k).Priority then failwith "incr" ;
f.Tbl.(k) < {Priority = c; Value = f.Tbl.(k).Value} ;
monte f.Tbl k ;;

4.

Exercices

4.1

Arbres binaires


Exercice 1  Dfinir une fonction Caml qui prend en arguments un entier p et un arbre binaire A et qui
retourne la liste des sous-arbres non vides dont la racine est la profondeur p dans A.
Lorsque A est un arbre binaire complet de hauteur p, combien dinsertions en tte de liste votre fonction
effectue-t-elle ?

Exercice 2  Un arbre binaire A est complet lorsque ses fils gauche et droit sont complets et de mme hauteur.
Pour dterminer si un arbre binaire est complet, on propose la fonction suivante :
let rec est_complet = function
| Nil
> true
| Noeud (fg, _, fd) > est_complet fg && est_complet fd
&& hauteur fg = hauteur fd ;;

valuer en fonction de n = |A| le cot temporel de cette fonction. Peut-on faire mieux ?

Exercice 3  Dfinir une fonction Caml qui prend en argument un entier n et qui retourne le squelette dun
arbre binaire complet de taille n sil en existe, et dclenche une exception sinon. On utilisera le type :
type squelette = Nil | Noeud of squelette * squelette ;;


Exercice 4  Un arbre de Fibonacci dordre p est :
larbre vide si p = 0 ;
un arbre rduit une feuille si p = 1 ;
un arbre dont le fils gauche est un arbre de Fibonacci dordre p 1 et le fils droit un arbre de Fibonacci
dordre p 2 si p > 2.
Dessiner le squelette dun arbre de Fibonacci dordre 5. Combien un arbre de Fibonacci possde-t-il de feuilles ?
Calculer le dsquilibre en tout nud dun arbre de Fibonacci.

Exercice 5  Dfinir une fonction Caml qui dtermine avec une complexit en O(|A|) si un arbre binaire A est
un arbre AVL.

Exercice 6  On appelle arbre rouge-noir un arbre binaire comportant un champ supplmentaire par nud :
sa couleur, qui peut tre rouge ou noire, et qui vrifie les conditions suivantes :
la racine est noire ;
le parent dun nud rouge est noir ;
pour chaque nud, tous les chemins le reliant des feuilles (nil) contiennent le mme nombre de nuds
noirs.

Arbres binaires

1.15

a) Montrer que larbre ci-dessous peut tre muni dune coloration rouge-noir.

b) Donner un exemple darbre qui ne puisse pas tre muni dune coloration rouge-noir.
c) tant donn un arbre rouge-noir A, on note b(A) le nombre de nuds noirs que contient chacun des chemins
dun nil la racine (indpendant du choix de la feuille par dfinition).
Montrer que b(A) 6 h(A) + 1 6 2b(A) et que |A| > 2b(A) 1, et en dduire que les arbres rouge-noir sont quilibrs.
d) On dfinit le type :
type couleur = Rouge | Noir ;;

Dfinir en Caml une fonction qui dtermine si un lment de type couleur arbre est un arbre rouge-noir.
Lalgorithme choisi devra tre de cot linaire vis--vis de |A|.

4.2

Arbres binaires de recherche


Exercice 7  Ecrire une fonction Caml de type ( a, b) data arbre > bool qui dtermine si un arbre pass en
paramtre est un ABR.

Exercice 8  On peut trier un tableau de n nombres en commenant par les insrer un par un dans un arbre
binaire de recherche puis en les ordonnant suivant un parcours infixe. Rdiger la fonction Caml correspondante
puis tudier les temps dexcution de cet algorithme dans le pire et le meilleur des cas.

Exercice 9  Proposer plusieurs solutions pour fusionner deux arbres binaires de recherche A1 et A2 et rdiger
en Caml celle qui vous parait la meilleure.

Exercice 10  Soit A un arbre binaire de recherche et y lun de ses nuds. Une rotation droite autour de y
consiste faire descendre ce nud et faire remonter sont fils gauche x sans invalider lordre des lments :

x
rotation droite

A
rotation gauche

Lopration inverse sappelle rotation gauche autour du sommet x.


a) Montrer quune rotation prserve la structure darbre binaire de recherche et peut se raliser cot
constant lorsquelle est effectue autour de la racine (on crira explicitement les deux fonctions rotd et rotg
correspondantes, de type a arbre > a arbre).
b) Appliquer une rotation gauche autour de y puis une rotation droite autour de x dans larbre suivant :
Jean-Pierre Becirspahic

1.16

option informatique

x
y

D
z

A
B

c) On considre dsormais un arbre binaire de recherche qui respecte la condition AVL, savoir que le
dsquilibre de chaque nud est gal 1, 0 ou 1, et on considre une insertion qui a conduit la cration
dune feuille f . Seuls les anctres de f ont vu leur dsquilibre modifi ; on suppose que lun au moins ne
respecte plus la condition AVL et on note y le premier de ceux-l.
(i) Montrer que eq(y) = 2. Sans perte de gnralit on suppose dsormais eq(y) = 2 et on note x le fils gauche
de y.
(ii) Montrer que si eq(x) = 0 ou eq(x) = 1 une rotation suffit pour retrouver la condition AVL.
(iii) Montrer que si eq(x) = 1, deux rotations suffisent pour retrouver la condition AVL.

4.3

Tas binaires


Exercice 11 
a) Dfinir une fonction Caml tab_of_arbre qui prend en argument un arbre (parfait) de type int arbre et qui
retourne sa reprsentation sous la forme dun tableau de type int vect .
b) Dfinir la fonction inverse arbre_of_tab.

Exercice 12 
a) Montrer que dans un tas reprsent par un tableau Caml n cases les feuilles correspondent aux indices
jnk
suprieurs ou gaux
.
2
l n m
b) Montrer que dans un tas de taille n le nombre de noeuds de hauteur h est au plus gal h+1 .
2

Exercice 13  Rdiger en Caml une fonction qui retourne llment maximal dun tas-min.

Exercice 14  Un arbre binomial dordre p est :
un arbre rduit une feuille si p = 0 ;
un arbre qui admet p fils qui sont respectivement des arbres binomiaux dordre p 1, p 2, . . . , 1, 0.
a) Dessiner le squelette dun arbre binomial dordre 4, puis exprimer en fonction de p :
la taille dun arbre binomial dordre p ;
la hauteur dun arbre binomial dordre p ;
le nombre de nuds de profondeur k dun arbre binomial dordre p.
Un tas binomial est une arbre binomial qui a une structure de tas : linformation porte par un nud est (dans
le cas dun tas-min) infrieure ou gale linformation porte par chacun de ses fils. Nous allons tudier
un algorithme de conversion dun tas binaire de taille 2p en un tas binomial dordre p sans faire aucune
comparaison.
b) Un tas binaire A de taille 2p (p > 1) est constitu dune racine r, dun sous-arbre gauche Fg qui est un tas de
taille 2p1 et dun sous-arbre droit Fd qui est un tas de taille 2p1 1. Dcrire un algorithme qui transforme en
un tas binaire de taille 2p1 le sous-arbre droit Fd et la racine r. Prcisez le nombre doprations effectues.
c) Les deux tas binaires obtenus, Fg et le nouveau tas cr la question prcdente, sont transforms rcursivement en tas binomiaux dordre p 1. Expliquer comment les runir pour former un tas binomial dordre
p.
d) Illustrer cet algorithme en transformant en tas binomial le tas binaire suivant :

Arbres binaires

1.17

1
3

8
11

7
14

13

5
16

12

4
6

10

15
e) Calculer le nombre total dchanges dans un tas binaire ainsi que le nombre de concatnations de tas
binomiaux effectus lors de la conversion dun tas binaire de taille 2p . Sachant que ces oprations peuvent tre
ralises cot constant, quel est le cot total de lalgorithme ?

Jean-Pierre Becirspahic

S-ar putea să vă placă și