Aller au contenu

Arbres binaires

Un arbre binaire est un arbre d’arité deux. On peut aussi dire qu'un arbre binaire est un arbre dont chaque nœud possède au plus deux fils.

Sous-arbres d'un arbre binaire

On différencie les deux sous-arbres : le sous-arbre gauche et sous-arbre droit.

image

Les deux sous arbres peuvent être vides.

Question

Quels sont les sous arbres du nœud O ?

image

Arbres binaires complets

On rencontre très souvent des arbres binaires dits complets parce qu'aucun des fils gauche ou droit n'est manquant.

image

Question

Quelle est la taille d'un arbre binaire complet de hauteur \(h\) ?

Encadrement de la hauteur d'un arbre binaire

Nous avons vu que la hauteur d'un arbre filiforme était de :
\(h\) = \(\tau\) - 1

De plus, nous pouvons déterminer (expliqué au tableau) que la hauteur d'un arbre binaire complet est :
\(h = \lfloor \log_2 \tau \rfloor\)

On en déduit donc que :
\(\lfloor \log_2 \tau \rfloor \leq h \leq \tau - 1\)

Encadrement de la taille d'un arbre binaire

Nous avons vu que la hauteur d'un arbre filiforme était de :
\(h\) = \(\tau\) - 1

On en déduit que :
\(\tau\) = \(h\) + 1

Soit A un arbre binaire complet, nous avons vu que :
\(\tau = 2^{h + 1} - 1\)

On en déduit donc que :
\(h + 1 \leq \tau \leq 2^{h + 1} - 1\)

Arbres binaires de recherche

La recherche d’un élément dans un arbre a une complexité de l’ordre du nombre d’éléments \(\tau\).
Ce n’est pas mieux qu’une liste ! On cherche donc à optimiser la structure.

Définition

Un arbre binaire de recherche (ABR) est un arbre qui vérifie :

  • Tous les éléments du sous-arbre gauche sont strictement inférieurs à la racine.
  • Tous les éléments du sous-arbre droite sont strictement supérieurs à la racine.
  • Les deux sous-arbres sont des arbres binaires de recherche.

Exercice

Parmi les arbres ci-dessous, détérminez ceux qui sont des arbres binaires de recherche :

a)

image

b)

image

Un arbre binaire est équilibré si tous les chemins de la racine aux feuilles ont pour longueur \(h\) ou \(h-1\) .

Arbre équilibré

Parmi les arbres binaires de recherche ci-dessous, déterminez ceux qui sont équilibrés :

a)

image

b)

image

Algorithmie

Savoir utiliser la récursivité pour résoudre des problèmes algorithmiques sur les arbres binaires est fondamental dans ce cours.

Calcul de la hauteur et de la taille et de la hauteur (vu en TD et TP)

La taille \(\tau\) d'un arbre \(A\) se calcule récursivement :

A chaque appel, on renvoie 1 + taille(gauche(A)) + taille(droite(A)). Dans le cas de base, en cas d’absence de noeud, on renvoie 0.

taille(Arbre A) :
    Si A vide
        retourner 0
    retourner 1 + taille(gauche(A)) + taille(droite(A))

La hauteur \(h\) d'un arbre \(A\) se calcule récursivement :

  • un arbre vide a une hauteur de -1 (ou 0 en fonction de la convention choisie)
  • un arbre non vide a pour hauteur 1 + la hauteur maximale de ses deux sous'arbres

Pseudo-code :

hauteur(Arbre A) :
    Si A vide
        retourner - 1
    retourner 1 + max(hauteur(gauche(A)), hauteur(droite(A)))

Parcours de l'arbre

Parcours en profondeur (vu en TD et TP)

On cherche à parcourir les nœuds d’un arbre. Le parcours en profondeur traite les enfants en priorité.

Principe de l’algorithme :

  • Si l’arbre est vide, on s’interrompt
  • Sinon, selon l’ordre de priorité choisi :
    ➢ On traite la racine
    ➢ On parcourt récursivement le sous-arbre gauche
    ➢ On parcourt récursivement le sous-arbre droit

Suivant l’ordre de traitement des deux sous-arbres par rapport à la racine, nous avons en réalité trois parcours en profondeur différent :

  • le parcours préfixe traite la racine avant les deux sous-arbres
  • le parcours infixe traite la racine entre les deux sous-arbres
  • le parcours postfixe traite la racine après les deux sous-arbres

Parcours en largeur (vu en TD)

Le parcours en largeur (BFS pour Breadth First Search) consiste à parcourir l'arbre niveau par niveau.

Algorithmie sur les arbres binaires de recherche

Recherche d'une clé

Les arbres binaires de recherche sont très utilisés car ils permettent de retrouver et d'insérer des données rapidement. On les retrouve par exemple logiquement dans les SGBD (Système de Gestion de Bases de Données).

Nous allons rappeler le principe de la recherche dichotomique qui est censé avoir été vu en première.

Lorsque l'on est en présence d'un tableau qui contient des données triées :

[3, 3, 5, 6, 8, 11, 13, 14, 14, 17, 19, 21, 23]

Et que l'on souhaite chercher une valeur dans ce tableau, alors on pourra utiliser ce qu'on appelle une recherche dichotomique.

Définition du dictionnaire "Larousse"

Dichotomique : qui se divise et se subdivise de deux en deux, qui repose sur une division binaire : Classification dichotomique.

Cela consiste à diviser à chaque fois le tableau en deux et à vérifier si l'élément au milieu du tableau est inférieur ou supérieur à la valeur que l'on recherche.

Etant donné que l'on divise l'espace de recherche par deux à chaque itération la complexité algorithmique de cet algorithmique est de \(O(log_2(n))\), contre \(O(n)\) si on parcours chacun des éléments du tableau un à un.

Dans le cas d'un arbre binaire de recherche pour que la recherche se fasse en \(O(log_2(n))\) l'arbre doit être équilibré. Dans le pire des cas cette complexité sera de \(O(n)\), pensez par exemple au cas d'un arbre binaire de recherche qui serait filiforme.

On peut alors éliminer la moitié de l’arbre à chaque itération. Contrairement à un tableau (une liste Python) l'insertion peut également se faire en \(O(log_2(n))\).

recherche_cle : Recherche d'une clé
_________________________
entrée : A, un arbre binaire de recherche
entrée : clé, la clé (valeur) recherchée
sortie : Vrai si la clé (valeur) recherchée est dans l'arbre, Faux sinon.
_________________________

    Si A est vide
        Sortir : Faux

    Si A.racine =  clé
        Sortir : Vrai

    Si A.racine < clé
        Sortir : recherche_cle(A.gauche, clé)

    Si A.racine > clé
        Sortir : recherche_cle(A.droite, clé)

Insertion d'une clé

L'insertion d'un nœud commence par une recherche : on cherche la clé du nœud à insérer ; lorsqu'on arrive à une feuille, on ajoute le nœud comme fils de la feuille en comparant sa clé à celle de la feuille : si elle est inférieure, le nouveau nœud sera à gauche ; sinon il sera à droite.

inserer_cle : Insérer une clé
_________________________
entrée : A, un arbre binaire de recherche
entrée : clé, la clé (valeur) à insérer
_________________________

    Si A est vide
        A.racine = clé

    Si clé < A.racine.valeur
        inserer_cle(A.sous_arbre_gauche, clé)

    Si clé > A.racine.valeur
        inserer_cle(A.sous_arbre_droit, clé)