Arbre binaire de recherche

Classe ABR


def ajouter(arbre,valeur):
    if arbre is None:
        return Noeud(valeur,None,None)
    if valeur < arbre.valeur:
        return Noeud(arbre.valeur,
        ajouter(arbre.gauche,valeur),arbre.droit)
    elif valeur > arbre.valeur:
        return Noeud(arbre.valeur,arbre.gauche,
        ajouter(arbre.droit,valeur))
    else:
        return arbre

def rechercher(arbre,valeur):
    if arbre is None:
        return False
    if valeur < arbre.valeur:
        return rechercher(arbre.gauche,valeur)
    elif valeur > arbre.valeur:
        return rechercher(arbre.droit,valeur)
    else:
        return True




class ABR:
    def __init__(self):
        self.racine = None

    def ajouter(self,val):
        self.racine = ajouter(self.racine,val)

    def rechercher(self,val):
        return rechercher(self.racine,val)

Ajouter les méthodes suivantes

Pour visualiser l'arbre utiliser graphviz comme au TP sur les arbres

Equilibre d'un ABR

Un arbre binaire de recherche dégénéré de n sommets a une taille de n et une hauteur de n aussi

Un arbre binaire de recherche complet de taille $2^{n} - 1$ a une hauteur $n$

Le quotient, appelé ici coefficient d'équilibre, $\dfrac{\ln_2(n+1)}{h}$ mesure le fait qu'un arbre binaire de recherche soit plus ou moins complet, donc plus ou moins "équilibré" et varie entre 1 le maximum pour un arbre complet et parfaitement équilibré et $\dfrac{\ln_2(n+1)}{n}$ le minimum pour un arbre dégénéré donc le plus déséquilibré possible

Tas

Un arbre binaire de recherche peut être redéfini comme un arbre binaire ordonné horizontalement.

Qu'est ce qu'un arbre binaire orienté verticalement ?

Un arbre binaire est orienté verticalement si pour tout noeud autre qu'une feuille la valeur de ce noeud est inférieur à celle de ses deux fils.

Un arbre binaire est essentiellement complet si tous les niveaux sont complets à part le dernier peut-être et toutes les feuilles sont tassées à gauche.

Un tas min T est un arbre binaire essentiellement complet orienté verticalement.

Un tas max T est un arbre binaire essentiellement complet vérifiant:

Pour tout noeud i : T[parent(i)] >= T[i]

En conséquence contrairement aux arbres binaires de recherche les valeurs des sous arbre gauche et sous arbre droit d'un noeud sont inférieures ou égales à la valeur du noeud.

De plus le plus grand élément du tas max est la racine de l'arbre.

Pourquoi s'intéresser aux tas ?

Exemple

On range les valeurs d'un tas dans un tableau T ainsi :

Dans T[0] on met la taille de l'arbre

Pour un noeud i rangé dans T[i], le fils droit est rangé dans T[2*i] le fils gauche dans T[2*i +1]

Pour un noeud i rangé dans T[i], son père est rangé en T[i//2].

On veut implémenter une classe Tas_max avec les méthodes suivantes :

On crée un tas vide mais de taille n,puis ensuite :

File de priorité

On crée une classe de tâches domestiques nommée Tache ayant deux attributs

Exercices

  1. Ecrire les méthodes __lt__() (pour lesser than) et __le__() (pour lesser than or equals) permettant de comparer des objets de type Tache suivant leur cle
  2. Créer des tâches et les comparer, par exemple:
    
    >>> t1 = Tache("Repas",2)
    >>> t5 = Tache("Courses",6)
    >>> t1 < t5
    True
    
    
  3. Ajouter les méthodes __gt()__ et __ge__()
  4. Proposer une implémentation d'une file de priorité avec un tableau

    Evaluer le coût d'une insertion dans la file de pririté, et le coût d'une suppression

  5. Grâce aux méthodes __lt__(), __le__(), __gt()__ et __ge__() on peut utiliser la classe Tas_max pour faire une file de priorité avec les taches.

    Essayer

    
    t1 = Tache("Repas",2)
    t2 = Tache("Vaisselle",7)
    t3 = Tache("Lessive",5)
    t4 = Tache("Sol",1)
    t5 = Tache("Courses",6)
    
    liste_taches = [t1,t2,t3,t4,t5]
    
    fp  = Tas_max(5)
    fp.cree_tas_max(liste_taches)
    
    print(fp.maximum())
    
    print(fp.supprime_racine())
    
    
  6. Une tâche étant dans la file de priorité peut voir sa priorité augmenter

    Proposer une solution à ce problème