Arbres binaires
Introduction
Quand les données ont une hiérarchie naturelle — un système de fichiers, un arbre généalogique, le DOM d'une page web, la décomposition syntaxique d'une expression — les structures linéaires ne suffisent plus. On utilise alors un arbre : un ensemble de nœuds organisés autour d'une racine, où chaque nœud porte un nombre fini d'enfants.
L'image la plus familière est l'arbre généalogique : une personne en haut, ses descendants qui se ramifient à mesure qu'on descend. La racine informatique est en haut par convention — les arbres en informatique poussent vers le bas, contrairement à leurs cousins botaniques.
Ce cours traite spécifiquement des arbres binaires (chaque nœud a au plus deux enfants), conformément à . Les algorithmes associés (parcours préfixe, infixe, suffixe, BFS, DFS) sont abordés au chapitre TE.
Vocabulaire
| Terme | Définition |
|---|---|
| Nœud | Élément de l'arbre, portant une valeur. |
| Racine | Nœud sans parent — point d'entrée unique de l'arbre. |
| Feuille | Nœud sans enfant. |
| Sous-arbre gauche | Arbre enraciné au fils gauche d'un nœud. |
| Sous-arbre droit | Arbre enraciné au fils droit. |
| Arête | Lien entre un parent et un de ses enfants. |
| Taille | Nombre total de nœuds de l'arbre. |
| Hauteur | Longueur (en arêtes) du plus long chemin de la racine à une feuille. |
| Profondeur d'un nœud | Longueur du chemin de la racine à ce nœud. |
Implémentation Python
On reprend l'outil objet du cours précédent. Un nœud est un objet portant une
valeur, un fils gauche et un fils droit (qui sont eux-mêmes des nœuds ou None).
class Noeud:
"""Nœud d'un arbre binaire."""
def __init__(self, valeur, gauche=None, droite=None):
self.valeur = valeur
self.gauche = gauche
self.droite = droite
def est_feuille(self):
return self.gauche is None and self.droite is None
Création d'un petit arbre :
# 1
# / \
# 2 3
# /
# 4
arbre = Noeud(1, Noeud(2, Noeud(4)), Noeud(3))
Dans l'arbre ci-dessus, combien de feuilles ?
Mesurer un arbre binaire
Taille
Le nombre total de nœuds, défini récursivement :
def taille(noeud):
if noeud is None:
return 0
return 1 + taille(noeud.gauche) + taille(noeud.droite)
Hauteur
La convention rend la formule cohérente : un arbre à un seul nœud a alors une hauteur .
def hauteur(noeud):
if noeud is None:
return -1
return 1 + max(hauteur(noeud.gauche), hauteur(noeud.droite))
Encadrement de la hauteur
Question canonique du BO : pour un arbre binaire de taille et de hauteur , peut-on borner en fonction de ?
Théorème
Pour tout arbre binaire non vide de taille et de hauteur :
de manière équivalente :
Preuve par récurrence
Montrons : un arbre binaire de hauteur vérifie .
Initialisation (). L'arbre est réduit à sa racine. On a , et , et . L'inégalité tient.
Hérédité. Supposons la propriété vraie pour toute hauteur strictement inférieure à (avec ). Soit un arbre binaire de hauteur . Ses sous-arbres et ont chacun une hauteur , et au moins l'un des deux atteint (sinon aurait une hauteur strictement inférieure à ).
- Minoration. Le sous-arbre qui atteint contient au moins nœuds par hypothèse de récurrence. Avec la racine de , on a donc .
- Majoration. Chaque sous-arbre a au plus nœuds par hypothèse de récurrence. Donc
L'inégalité est démontrée pour la hauteur . Par récurrence, elle est vraie pour tout . Par passage au logarithme dans la majoration , on obtient , ce qui ferme l'équivalence annoncée.
Conséquences
- Un arbre filiforme (chaque nœud n'a qu'un seul enfant) atteint la borne basse : , donc .
- Un arbre parfaitement équilibré et complet atteint la borne haute : , donc , soit .
- C'est pour cela que les structures arborescentes équilibrées sont recherchées : leurs opérations sont en au lieu de .
Un arbre binaire de hauteur h=3h = 3h=3 contient au plus combien de nœuds ?
Pour aller plus loin
Les arbres binaires de recherche (ABR), les tas binaires et les arbres équilibrés (AVL, rouge-noir) exploitent cette propriété d'encadrement pour garantir des opérations en . Vous reviendrez sur certains d'entre eux au chapitre TE.