Algorithmique

⚙️ Chapitre : Algorithmes sur les arbres

1️⃣ Création de la classe

Pour implémenter un arbre binaire, on peut utiliser la POO en utilisant une classe Node:


class Node:
    def __init__(self, val):
        # Attributs de l'objet
        self.val = val
        self.gauche = None
        self.droit = None

La structure d’un arbre permet de représenter des relations de dépendance ou d’organisation.



2️⃣ Instanciation d'un arbre

8 3 10 1 6 14

Pour créer cet arbre, procédons ainsi :


arbre = Node('8') # Instanciation de la racine
# Sous-arbre gauche
arbre.gauche = Node('3')
arbre.gauche.gauche = Node('1')
arbre.gauche.droit = Node('6')
# Sous-arbre droit
arbre.droit= Node('10')
arbre.droit.droit= Node('14')



3️⃣ Parcours en profondeur (DFS)

Le parcours en profondeur qui utilise la récursivité et se fait selon trois méthodes différentes que vous devez connaitre : préfixe, infixe ou suffixe.

Parcours préfixe (preorder) :


def prefixe(arbre):
    # cas de base
    if arbre==None:
        return
    else:
        print(arbre.val,end='→')
        prefixe(arbre.gauche)
        prefixe(arbre.droit)
# appel
prefixe(arbre)


Affiche: 8 → 3 → 1 → 6 → 10 → 14

Parcours infixe (inorder) :


def infixe(arbre):
    # cas de base
    if arbre==None:
        return
    else:
        infixe(arbre.gauche)
        print(arbre.val,end='→')
        infixe(arbre.droit)
# appel
infixe(arbre)



Affiche: 1 → 3 → 6 → 8 → 10 → 14

Parcours postfixe (postorder) :


def postfixe(arbre):
    # cas de base
    if arbre==None:
        return
    else:       
        postixe(arbre.gauche)
        postixe(arbre.droit)
        print(arbre.val,end='→')
# appel
postfixe(arbre)


Affiche: 1 → 6 → 3 → 10 → 14 → 8



3️⃣ Parcours en largeur

8 3 10 1 6 14

Le parcours en largeur qui consiste à afficher les valeurs des nœuds niveau par niveau, de gauche à droite en commençant par la racine. On utilise pour cela une file pour garder en mémoire le fils gauche et le fils droit du nœud visité jusqu´à ce que la file soit vide.


On ne détaille pas l'algorithme ici mais vous devez le pratiquer. Au bac, un code vous sera fournit, il faut savoir le compléter.


Parcours en largeur: 8 → 3 → 10 → 1 → 6 → 14



4️⃣ Algorithmes classiques

Hauteur d'un arbre, on utilise la fonction max de Python:


def hauteur(arbre):
    # Cas de base : arbre vide, hauteur 0
    if arbre is None:
        return 0
    # Calcul récursif : 1 + max(hauteur gauche, hauteur droit)
    else:
        return 1 + max(hauteur(arbre.gauche), hauteur(arbre.droit))
print(hauteur(arbre)) # affiche 3

Taille d'un arbre (nombre de noeuds), c'est une variante du précédent:


def taille (arbre):
    # Cas de base : arbre vide, pas de noeud
    if arbre == None:
        return 0
    else:
        return 1+taille(arbre.gauche)+taille(arbre.droit)
taille(arbre) # affiche 6



5️⃣ Arbres binaires de recherche

Un arbre binaire de recherche (ABR) est un arbre binaire tel que :

Cette propriété permet d’effectuer une recherche efficace d’une valeur.

Principe de la recherche

Pour rechercher une valeur \( x \) :

À chaque étape, on élimine la moitié des valeurs possibles.

Complexité

La complexité dépend de la hauteur \( h \) de l’arbre.

Dans le cas général :

\[ T(n) = \mathcal{O}(h) \]

Si l’arbre est équilibré, sa hauteur vérifie :

\[ h \approx \log_2(n) \]

Donc la complexité devient :

\[ T(n) = \mathcal{O}(\log n) \]

En revanche, si l’arbre est dégénéré (chaîne linéaire), alors :

\[ h = n \quad \Rightarrow \quad T(n) = \mathcal{O}(n) \]

Conclusion



🔗 Un exercice intéressant, centres étrangers – 2023.
🔗 Cet autre exercice de Polynésie porte sur les arbres binaires, les arbres binaires de recherche, la programmation orientée objet et la récursivité.