Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Arbres binaires de recherche

Après cette leçon: Je peux construire un arbre binaire de recherche et y chercher une valeur.

Leçon de 60 min2 commandesLab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

Chercher un mot dans un dictionnaire papier

Un arbre binaire de recherche est une structure de nœuds rangés de façon que chaque comparaison écarte une moitié des valeurs. Il retrouve une valeur en une dizaine d’étapes parmi mille.

Pour chercher un mot dans un dictionnaire papier, on l’ouvre au milieu. Le mot est avant ou après : on garde une moitié, puis on recommence. Un arbre de recherche range ses valeurs pour faire la même chose.

À la fin de cette leçon

Remarque

Je peux construire un arbre binaire de recherche et y chercher une valeur.

Mots-clés

MotCe que ça veut dire
Arbredes nœuds reliés du haut vers le bas
Racinele nœud tout en haut de l’arbre
Feuilleun nœud qui n’a aucun enfant
Sous-arbreun nœud et tout ce qui est en dessous de lui
Arbre binaire de rechercheun arbre où le plus petit est à gauche et le plus grand à droite
Parcours infixevisiter la gauche, puis le nœud, puis la droite

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Chaque nœud a au plus deux enfants

Un arbre est fait de nœuds reliés du haut vers le bas. Le nœud tout en haut est la racine.

Dans un arbre binaire, chaque nœud a au plus deux enfants : un à gauche et un à droite. Un nœud sans enfant est une feuille. Un nœud et tout ce qui est en dessous forment un sous-arbre.

Petit à gauche, grand à droite

Dans un arbre binaire de recherche, tout ce qui est à gauche d’un nœud est plus petit que lui. Tout ce qui est à droite est plus grand.

Cette règle vaut pour chaque nœud, pas seulement pour la racine. Chercher revient donc à choisir un côté à chaque pas.

Exemple travaillé : chercher 60 dans le schéma

ÉtapeNœud luComparaisonSuite
15060 est plus grand que 50Aller à droite
27060 est plus petit que 70Aller à gauche
36060 est égal à 60Trouvé

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Insérer, c’est chercher la place libre

Pour insérer une valeur, on la cherche comme si elle était là. On descend à gauche ou à droite, jusqu’à tomber sur une place vide.

La valeur devient une nouvelle feuille, accrochée à cet endroit. On ne déplace aucun nœud. Une valeur déjà présente n’est pas ajoutée une seconde fois.

Exemple travaillé : insérer 45 dans le schéma

ÉtapeNœud luComparaisonSuite
15045 est plus petitAller à gauche
23045 est plus grandAller à droite
34045 est plus grand, et 40 n’a pas d’enfant droitAccrocher 45 à droite de 40

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Insérer des valeurs à lancer

Code: python
class Noeud:
    def __init__(self, valeur):
        self.valeur = valeur
        self.gauche = None
        self.droite = None

def inserer(racine, valeur):
    if racine is None:
        return Noeud(valeur)
    courant = racine
    while True:
        if valeur < courant.valeur:
            if courant.gauche is None:
                courant.gauche = Noeud(valeur)
                return racine
            courant = courant.gauche
        elif valeur > courant.valeur:
            if courant.droite is None:
                courant.droite = Noeud(valeur)
                return racine
            courant = courant.droite
        else:
            return racine  # déjà présente : rien à faire

racine = None
for v in [50, 30, 70, 20, 40]:
    racine = inserer(racine, v)
racine = inserer(racine, 45)
print(racine.gauche.droite.droite.valeur)

Le parcours infixe lit les valeurs dans l’ordre

Le parcours infixe visite le sous-arbre gauche, puis le nœud, puis le sous-arbre droit. Dans un arbre de recherche, il donne les valeurs triées.

On l’écrit avec la récursivité : une fonction qui s’appelle elle-même sur un sous-arbre plus petit. Elle s’arrête sur un arbre vide, qu’on appelle le cas de base.

Exemple travaillé : le parcours infixe du schéma

ÉtapeCe qu’on faitValeurs lues
1Descendre tout à gauche, jusqu’à 2020
2Remonter au nœud 3020, 30
3Visiter la droite de 30 : 4020, 30, 40
4Remonter à la racine 5020, 30, 40, 50
5Visiter le sous-arbre droit : 60, 70, 8020, 30, 40, 50, 60, 70, 80

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Un parcours récursif à lancer

Code: python
class Noeud:
    def __init__(self, valeur):
        self.valeur = valeur
        self.gauche = None
        self.droite = None


racine = Noeud(50)
racine.gauche = Noeud(30)
racine.droite = Noeud(70)
racine.gauche.droite = Noeud(40)


def parcours_infixe(racine):
    if racine is None:  # cas de base : un arbre vide
        return []
    gauche = parcours_infixe(racine.gauche)
    droite = parcours_infixe(racine.droite)
    return gauche + [racine.valeur] + droite


print(parcours_infixe(racine))
# Ajoutez racine.droite.droite = Noeud(90), puis relancez.

Chercher coûte la hauteur de l’arbre

Chaque pas descend d’un niveau. Chercher coûte donc au plus la hauteur de l’arbre, c’est-à-dire son nombre de niveaux.

Si l’arbre est bien rempli, chaque niveau double le nombre de places. Dix niveaux suffisent pour environ mille valeurs, vingt pour environ un million. Les deux commandes montrent ces nombres.

Arbre équilibré ou arbre en chaîne

ValeursPas au plus, arbre équilibréPas au plus, arbre en chaîne
737
1 000101 000
1 000 000201 000 000

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Niveaux pour mille et un million de valeurs

Commande
python3 -c "import math; print(math.ceil(math.log2(1000)), math.ceil(math.log2(1000000)))"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Les places que contiennent 10 et 20 niveaux

Commande
python3 -c "print(2 ** 10, 2 ** 20)"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Erreur fréquente

Attention

Beaucoup pensent qu’un arbre de recherche est toujours rapide. Ce n’est pas vrai. Si l’on insère des valeurs déjà triées, 1, 2, 3, 4, chacune va à droite et l’arbre devient une chaîne. Chercher coûte alors autant que dans une liste. La forme dépend de l’ordre des insertions.

Pour aller plus loin

Écrivez une fonction récursive hauteur(racine). Un arbre vide a la hauteur 0. Sinon, la hauteur est 1 plus la plus grande des hauteurs des deux sous-arbres.

Construisez un arbre avec 50, 30, 70, 20, 40, 60, 80, puis un autre avec 1, 2, 3, 4, 5, 6, 7. Comparez leurs hauteurs.

À propos de ce labo et de sa source: Lab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.