Algo AB Largeur

Identification

Infoforall

19 - Parcours en largeur d'abord (AB)


Après les parcours en profondeur (prefixe, infixe et suffixe), nous allons aujourd'hui voir comment explorer un arbre en partant de la racine et en explorant chaque niveau, profondeur par profondeur.

Prérequis :

  • Données : Arbre et Arbre Binaire
  • Algos : Parcours d'Arbres
  • Algos : Algorithmes des Arbres Binaires

Evaluation ✎ :

Documents de cours : open document ou pdf

Résumé : Version HTML ou fond blanc ou ou PDF (couleur ou gris)

1 - Principe du parcours en largeur

Ce parcours consiste à d'abord explorer le niveau "1" (qui ne contient que la racine). Puis le niveau 2...

Parcours en largeur

L'ordre de lecture des noeuds donne donc Alice - Bob - Clara - Didier - Eleonore...

Résumons ce que nous allons voir:

  • Le parcours en Profondeur d'abord utilise une Pile (soit la pile d'appels, soit une vraie pile).
  • Le parcours en largeur d'abord utilise une File.

2 - Algorithme de parcours en largeur

(Rappel) 2.1 Parcours en profondeur d'abord, version itérative

On remplace la pile d'appels par une vraie pile.

Description de l'ALGORITHME (sans précondition) (ici prefixe RGD)

Description de parcourir(arbre: Arbre Binaire)

    SI NON estABV(arbre)

      p nouvellePileVide()

      empiler(p, arbre)

      TANT QUE NON estPileVide(p)

        a depiler(p)

        visiter(racine(a))

        SI NON estABV(droite(a))

          empiler(p, droite(a))

        Fin SI


        SI NON estABV(gauche(a))

          empiler(p, gauche(a))

        Fin SI

      Fin TANT QUE

    Fin SI

    Renvoyer VIDE

Seul l'ordre des 3 blocs change dans les 3 versions.

L'algorithme préfixe en français

    Si l'arbre n'est pas VIDE

    1. Empiler l'arbre dans une Pile
    2. Tant que la Pile n'est pas vide
      1. Dépiler le prochain arbre, nommons le a.
      2. Explorer la racine de l'arbre a
      3. Si le sous-arbre droite (sad) de a n'est pas VIDE alors empiler le sad.
      4. Si le sous-arbre gauche (sag) de a n'est pas VIDE alors empiler le sag.
2.2 Parcours en largeur d'abord, version itérative

Description de l'ALGORITHME (sans précondition)

Description de parcourir(arbre: Arbre Binaire)

    SI NON estABV(arbre)

      f nouvelleFileVide()

      enfiler(f, arbre)

      TANT QUE NON estFileVide(f)

        a defiler(f)

        visiter(racine(a))

        SI NON estABV(gauche(a))

          enfiler(f, gauche(f))

        Fin SI


        SI NON estABV(droite(a))

          enfiler(f, droite(a))

        Fin SI

      Fin TANT QUE

    Fin SI

    Renvoyer VIDE

Lien avec l'algorithme en profondeur d'abord
  • Il s'agit d'une modification d'un profondeur d'abord en préfixe RGD
  • obtenue en utilisant une File et pas une Pile
  • avec des phases RGD (contrairement à la version profondeur avec pile en RDG)
L'algorithme du parcours en largeur d'abord en français

    Si l'arbre n'est pas VIDE

    1. Enfiler l'arbre dans une File
    2. Tant que la File n'est pas vide
      1. Défiler le prochain arbre, nommons le a.
      2. Explorer la racine de l'arbre a
      3. Si le sous-arbre gauche (sag) de a n'est pas VIDE alors empiler le sag.
      4. Si le sous-arbre droite (sad) de a n'est pas VIDE alors empiler le sad.

01° Appliquer l'algorithme du parcours en largeur à la main sur l'Arbre ci-dessous. Pour cela :

  • Ecrire le contenu de la File à chaque fin d'itération ;
  • Indiquer l'ordre dans lequel les clés sont visitées/affichées.
Arbre exercice

Vous devriez aboutir à l'affichage A-B-C-D.

...CORRECTION...

Votre version papier ne doit pas contenir tout cela mais voilà la description complète du parcours :

On enfile l'arbre aa = ("A", ∅, ab).

File : (arrière) aa (avant)

On démarre le TANT QUE.

  • On défile aa = ("A", ∅, ab) ;
  • On affiche "A" ;
  • Le sous-arbre gauche est vide ;.
  • Le sous-arbre droite n'est pas vide : on enfile ab.

File : (arrière) ab (avant)

Deuxième tour de TANT QUE.

  • On défile ab = ("B", ac, ad) ;
  • On affiche "B" ;
  • Le sous-arbre gauche n'est pas vide : on enfile ac ;
  • Le sous-arbre droite n'est pas vide : on enfile ad.

File : (arrière) ad ac (avant)


Troisième tour de TANT QUE.

  • On défile ac = ("C", ∅, ∅) ;
  • On affiche "C" ;
  • Aucun enfilement car les deux-sous arbres sont vides.

File : (arrière) ad (avant)

Quatrième tour de TANT QUE.

  • On défile ad = ("D", ∅, ∅) ;
  • On affiche "D" ;
  • Aucun enfilement car les deux-sous arbres sont vides.

File : vide

Fin du TANT QUE car la File est vide.

02° Même question en ne fournissant que les états successifs de la File à la fin de chaque tour.

Arbre de la partie 1

Début de la rédaction :

File : vide

File : (arrière) aa (avant)

File : (arrière) ae ac (avant)

...CORRECTION...

File : vide

File : (arrière) aa (avant)

File : (arrière) ae ac (avant)

File : (arrière) ab ag ae (avant)

File : (arrière) af ad ab ag (avant)

File : (arrière) ah af ad ab (avant)

File : (arrière) ah af ad (avant)

File : (arrière) ah af (avant)

File : (arrière) ah (avant)

File : vide

On aura donc le parcours A - C - E - G - B - D - F - H.

3 - Implémentation et programmation en Python

Nous avions utilisé le module arbre_binaire_ifa, nous allons simplement rajouter le module file_ifa et importer les fonctions d'interface pour gérer une File.

03° Créer la structure ci-dessous en utilisant les codes fournis des fichiers arbre_binaire_ifa.py et file_ifa.py.

📁 algoParcoursLargeur

📄 arbre_binaire_ifa.py

📄 file_ifa.py

Module arbre_binaire_ifa (objet)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
"""Module implémentant un Arbre Binaire (AB) avec un modèle objet Coûts et prototypes des primitives disponibles : [cst] nv_ABV() -> 'AB VIDE' [cst] nv_AB(valeur:'Element', g:'AB', d:'AB') -> 'AB NON VIDE' [cst] est_ABV(arbre:'AB') -> bool [cst] racine(arbre:'AB NON VIDE') -> 'Noeud' [cst] gauche(arbre:'AB NON VIDE') -> 'AB' [cst] droite(arbre:'AB NON VIDE') -> 'AB' [cst] contenu(noeud:'Noeud') -> 'Element' """ # Déclaration de la classe AB class AB: """Implémentation d'un Arbre Binaire""" def __init__(self, valeur, gauche, droite): self.v = valeur self.g = gauche self.d = droite def relier_a_gauche(self:'AB NON VIDE', sous_arbre:'AB'): """Méthode qui définit sous_arbre comme le sous-arbre gauche de l'arbre actif""" self.g = sous_arbre def relier_a_droite(self:'AB NON VIDE', sous_arbre:'AB'): """Méthode qui définit sous_arbre comme le sous-arbre droite de l'arbre actif""" self.d = sous_arbre def definir_donnees_racine(self:'AB', element:'Element NON VIDE'): """Méthode qui place l'élément NON VIDE en tant que racine de l'arbre""" self.v = element def vider(self:'AB'): """Méthode qui transforme l'arbre en AB VIDE""" self.v = None self.g = None self.d = None # Fonctions d'interface (accessibles de l'extérieur) def contenu(noeud:'Noeud') -> 'Element': """Renvoie le contenu associé au noeud fourni""" return noeud.v def nv_ABV() -> 'AB VIDE': """Renvoie un nouvel Arbre Binaire Vide""" return AB(None, None, None) def nv_AB(valeur:'Element', g:'AB', d:'AB') -> 'AB NON VIDE': """Renvoie un nouvel Arbre Binaire dont la racine porte valeur et qui mène aux sous-arbres g et d""" return AB(valeur, g, d) def est_ABV(arbre:'AB') -> bool: """Prédicat qui renvoie True si l'arbre est vide""" return arbre.v is None and arbre.g is None and arbre.d is None def racine(arbre:'AB NON VIDE') -> 'Noeud': """Renvoie le noeud-racine de l'Arbre Binaire NON VIDE""" return arbre # ici arbre et racine sont des alias def gauche(arbre:'AB NON VIDE') -> 'AB': """Renvoie le sous-arbre gauche de l'Arbre Binaire NON VIDE""" return arbre.g def droite(arbre:'AB NON VIDE') -> 'AB': """Renvoie le sous-arbre droite de l'Arbre Binaire NON VIDE""" return arbre.d # Programme de test du module if __name__ == "__main__": ad = nv_AB("D", nv_ABV(), nv_ABV()) af = nv_AB("F", ad, nv_ABV()) ae = nv_AB("E", nv_ABV(), af) ah = nv_AB("H", nv_ABV(), nv_ABV()) ag = nv_AB("G", nv_ABV(), ah) ab = nv_AB("B", nv_ABV(), nv_ABV()) ac = nv_AB("C", ag, ab) aa = nv_AB("A", ac, ae) print(contenu(racine(gauche(aa))))
Module file_ifa (modèle deque)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
"""Module implémentant une File avec un modèle deque, double ended queue Coûts et prototypes des primitives disponibles : [cst] nv_FV() -> File VIDE [cst] est_file_vide(f:File) -> bool [cst] enfiler(f:File, x:Element) -> None [cst] lire_avant(f:File NON VIDE) -> Elt [cst] defiler(f:File NON VIDE) -> Elt [cst] taille(f:File) -> int [lin] representation_file(f:File) -> str """ # Importation import collections # Fonction d'observation qui n'a rien à faire dans l'interface d'une File ! def representation_file(f): """Fonction debug, ce n'est pas une fonction d'interface.""" if not est_file_vide(f): tableau = list(f) reponse = "" for element in tableau: reponse = " -> " + str(element) + reponse reponse = "(arrière) " + reponse + " (avant)" else: reponse = None return reponse # Fonctions d'interface de la File def nv_FV() -> 'File VIDE': """Renvoie la référence d'une File vide""" return collections.deque() def est_file_vide(f:'File') -> bool: """Prédicat qui teste si f est une File vide""" return f == collections.deque() def enfiler(f:'File', x:'Element') -> None: """On insére la nouvelle valeur x à l'Arrière de f""" f.append(x) def lire_avant(f:'File NON VIDE') -> 'Element': """On lit le contenu de l'Avant de la File f """ return f[0] def defiler(f:'File NON VIDE') -> 'Element': """On supprime et renvoie l'Avant de la File f (f peut être vide)""" return f.popleft() def taille(f:'File') -> int: """Renvoie la taille de la File f""" return len(f) if __name__ == '__main__': f = nv_FV() rajout = [5,10,15,20] for elt in rajout: enfiler(f, elt) print(representation_file(f)) defiler(f) print(representation_file(f))

04° Utiliser le fichier programme_parcours.py suivant. Il importe les deux modules précédents.

Deux questions :

  1. à quoi sert la ligne 15 ? Regarder notamment la ligne 45.
  2. représenter l'arbre construit par le programme de test.

📁 algoParcoursLargeur

📄 arbre_binaire_ifa.py

📄 file_ifa.py

📄 programme_parcours.py

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
# Importations from arbre_binaire_ifa import nv_ABV from arbre_binaire_ifa import nv_AB from arbre_binaire_ifa import est_ABV from arbre_binaire_ifa import racine from arbre_binaire_ifa import contenu from arbre_binaire_ifa import gauche from arbre_binaire_ifa import droite from file_ifa import nv_FV from file_ifa import est_file_vide from file_ifa import enfiler from file_ifa import defiler from file_ifa import taille as taille_file # Déclarations des fonctions def hauteur(arbre:'AB', profondeur_vide=-1) -> int: """Renvoie la hauteur de l'Arbre Binaire""" if est_ABV(arbre): return profondeur_vide else: return 1 + max(hauteur(gauche(arbre)), hauteur(droite(arbre))) def nb_feuilles(arbre:'AB') -> int: """Renvoie le nombre de feuilles de l'Arbre Binaire (arbre peut être vide)""" if est_ABV(arbre): return 0 elif est_ABV(gauche(arbre)) and est_ABV(droite(arbre)): return 1 else: return nb_feuilles(gauche(arbre)) + nb_feuilles(droite(arbre)) def taille(arbre:'AB') -> int: """Renvoie la taille de l'Arbre Binaire""" if est_ABV(arbre): return 0 elif est_ABV(gauche(arbre)) and est_ABV(droite(arbre)): return 1 else: return 1 + taille(gauche(arbre)) + taille(droite(arbre)) def est_present(arbre:'AB', c:'Clé') -> bool: """Prédicat : True si c est la clé d'un noeud""" if est_ABV(arbre): return False elif contenu(racine(arbre)) == c: return True else: return est_present(gauche(arbre), c) or est_present(droite(arbre), c) def parcours_prefixe_rec(arbre:'Arbre') -> None: """RECURSIVE Exploration (et affichage) en profondeur en préfixe RGD (arbre peut être vide)""" if not est_ABV(arbre): print(contenu(racine(arbre))) parcours_prefixe_rec(gauche(arbre)) parcours_prefixe_rec(droite(arbre)) def parcours_prefixe_ite(arbre:'Arbre') -> None: """ITERATIVE Exploration (et affichage) en profondeur en préfixe RGD (arbre peut être vide)""" pass def parcours_largeur(arbre:'Arbre') -> None: """Exploration (et affichage) en largeur de l'arbre (version iterative) (arbre peut être vide)""" pass def parcours_largeur_2(arbre:'Arbre') -> None: """Exploration (et affichage) en largeur de l'arbre (version récursive)(arbre peut être vide)""" pass # Instructions du programme principal if __name__ == "__main__": ah = nv_AB("H", nv_ABV(), nv_ABV()) af = nv_AB("F", nv_ABV(), nv_ABV()) ag = nv_AB("G", nv_ABV(), nv_ABV()) ac = nv_AB("C", af, ag) ad = nv_AB("D", nv_ABV(), ah) ae = nv_AB("E", nv_ABV(), nv_ABV()) ab = nv_AB("B", ad, ae) aa = nv_AB("A", ab, ac)

...CORRECTION...

La ligne 15 permet d'importer la fonction d'interface taille qui permet d'obtenir le nombre d'éléments dans la file. Comme il existe déjà une fonction taille dans notre programme (elle donne la taille de l'arbre binaire), on change le nom de la fonction importée.

Pour l'Arbre Binaire, il suffit de regarder ci-dessous.

L'Arbre Binaire créé dans le programme de test est le suivant :

Arbre de test

05° Mettre le programme de test en mémoire et lancer (dans la console) 4 appels à la fonction native help() pour aller retrouver la documentation (notamment le prototype pour savoir quoi envoyer) de 4 fonctions issues des modules.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# Importations from arbre_binaire_ifa import nv_ABV from arbre_binaire_ifa import nv_AB from arbre_binaire_ifa import est_ABV from arbre_binaire_ifa import racine from arbre_binaire_ifa import contenu from arbre_binaire_ifa import gauche from arbre_binaire_ifa import droite from file_ifa import nv_FV from file_ifa import est_file_vide from file_ifa import enfiler from file_ifa import defiler from file_ifa import taille as taille_file

Par exemple :

>>> help(enfiler) Help on function enfiler in module file_ifa: enfiler(f: 'File', x: 'Element') -> None On insére la nouvelle valeur x à l'Arrière de f

06° Donner en français l'algorithme du parcours en LARGEUR d'abord en version ITERATIVE. Voir le début de cours si vous bloquez.

...CORRECTION...

    Si l'arbre n'est pas VIDE

    1. Enfiler l'arbre dans une File
    2. Tant que la File n'est pas vide
      1. Défiler le prochain arbre, nommons le a.
      2. Explorer la racine de l'arbre a
      3. Si le sous-arbre gauche (sag) de a n'est pas VIDE alors empiler le sag.
      4. Si le sous-arbre droite (sad) de a n'est pas VIDE alors empiler le sad.

07° Compléter dans votre programme le code de la fonction parcours_largeur() (ligne 70+) pour qu'elle parvienne à implémenter l'algorithme proposé. Vous utiliserez le module file_ifa pour gérer la File nécessaire.

Vous devriez parvenir à explorer les noeuds dans l'ordre suivant :

>>> parcours_largeur(aa) A B C D E F G H

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11 12 13 14
def parcours_largeur(arbre:'AB') -> None: """Exploration (et affichage) en largeur de l'arbre (version iterative)""" if not est_ABV(arbre): f = nv_FV() enfiler(f, arbre) while not est_file_vide(f): a = defiler(f) print(contenu(racine(a))) g = gauche(a) if not est_ABV(g): enfiler(f, g) d = droite(a) if not est_ABV(d): enfiler(f, d)

08° Imaginons qu'on ne dispose pas du module file_ifa. Modifier votre fonction pour manipuler directement la File en tant que deque tiré du module collections plutot que d'utiliser le module file_ifa. Penser d'ailleurs à faire l'importation du deque.

Rappel : autant utiliser les mêmes extrémités qu'une File dont le modèle est une liste chaînée :

  • On enfile à droite dans le deque avec append() ;
  • On défile à gauche dans le deque avec popleft().

...CORRECTION...

... ... 1 2 3 4 5 6 7 8 9 10 11 12 13 14
import collections def parcours_largeur(arbre:'AB') -> None: """Exploration (et affichage) en largeur de l'arbre (version iterative)""" if not est_ABV(arbre): f = collections.deque() f.append(arbre) while f != collections.deque(): a = f.popleft() print(contenu(racine(a))) g = gauche(a) if not est_ABV(g): f.append(g) d = droite(a) if not est_ABV(d): f.append(d)

09° Modifier votre fonction en utilisant une "File du pauvre" : le modèle est une simple list Python plutôt qu'une deque

Rappel : autant utiliser les mêmes extrémités qu'une File dont le modèle est une liste chaînée :

  • On enfile à droite dans le deque avec append() ;
  • On défile à gauche dans le deque avec pop(0).

Question supplémentaire

Quel est le problème de cette implémentation ?

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11 12 13 14
def parcours_largeur(arbre:'AB') -> None: """Exploration (et affichage) en largeur de l'arbre (version iterative)""" if not est_ABV(arbre): f = [] f.append(arbre) while f != []: a = f.pop(0) print(contenu(racine(a))) g = gauche(a) if not est_ABV(g): f.append(g) d = droite(a) if not est_ABV(d): f.append(d)

Le problème est lié aux coûts des primitives : enfiler avec append() est bien constant mais le défilement avec pop(0) devient linéaire.

10° En vous inspirant de votre fonction de parcours en largeur, écrire la fonction python parcours_prefixe_ite() en utilisant la list Python pour simuler rapidement une Pile.

Attention à l'ordre des empilements des côtés gauche et droite.

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11 12 13 14
def parcours_prefixe_ite(arbre:'Arbre') -> None: """ITERATIVE Exploration (et affichage) en profondeur en préfixe RGD (arbre peut être vide)""" if not est_ABV(arbre): p = [] p.append(arbre) while p != []: a = p.pop() print(contenu(racine(a))) d = droite(a) if not est_ABV(d): p.append(d) g = gauche(a) if not est_ABV(g): p.append(g)

4 - Version récursive

Pour réaliser une version récursive, nous allons devoir utiliser une File qu'on transmettra en tant qu'argument à chaque appel récursif.

L'utilisation se fait alors en deux temps :

  1. On lance un appel à une première fonction non récursive parcours_largeur_2() en lui transmettant l'arbre sur lequel on doit travailler. Elle crée une File (ligne 4 ci-dessous) et y place l'arbre qu'on a reçu.
  2. parcours_largeur_2() lance alors un appel à notre fonction récursive nommée exploration_suivante().
1 2 3 4 5 6 7 8 9 10
def parcours_largeur_2(arbre:'AB') -> None: """Exploration (et affichage) en largeur de l'arbre (version récursive)""" if not est_ABV(arbre): f = nv_FV() enfiler(f, arbre) exploration_suivante(f) def exploration_suivante(f:'File') -> None: """Affiche la prochaine racine et stocke dans la File f les deux prochains sous-arbres détectés""" pass

11-A° Rajouter ces deux fonctions à votre programme.

1 2 3 4 5 6 7 8 9 10
def parcours_largeur_2(arbre:'AB') -> None: """Exploration (et affichage) en largeur de l'arbre (version récursive)""" if not est_ABV(arbre): f = nv_FV() enfiler(f, arbre) exploration_suivante(f) def exploration_suivante(f:'File') -> None: """Affiche la prochaine racine et stocke dans la File f les deux prochains sous-arbres détectés""" pass
11-B° Réaliser la fonction récursive exploration_suivante() pour qu'elle réagisse de cette façon :

  • Cas de base : la file est vide, on ne renvoie rien (et donc on sort de cet appel)
  • Cas récursif : il s'agit des instructions internes au TANT QUE de la version itérative. Le TANT QUE est donc remplacé par un appel récursif à la fonction.
    • étape 1 : on extrait le prochain AB et on affiche sa racine

      a defiler(f)

      visiter(racine(a))


      étape 2 : on voit si on rajoute le sous-arbre gauche dans la File

      g gauche(a)

      SI NON est_ABV(g)

        enfiler(f, g)

      Fin Si


      étape 3 : on voit si on rajoute le sous-arbre droite dans la File

      d droite(a)

      SI NON est_ABV(d)

        enfiler(f, d)

      Fin Si

      Renvoyer exploration_suivante(f)

On considère toujours une fonction visiter() qui ne fait qu'afficher dans la console la clé de la racine de l'arbre en cours d'exploration.

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
def parcours_largeur_2(arbre:'AB') -> None: """Exploration (et affichage) en largeur de l'arbre (version récursive)""" if not est_ABV(arbre): f = nv_FV() enfiler(arbre, f) exploration_suivante(f) def exploration_suivante(f:'File') -> None: """Affiche la prochaine racine et stocke dans la File f les deux prochains sous-arbres détectés""": if est_FV(f): # Condition d'arrêt return None # Cas de base else: # Cas récursif a = defiler(f) print(contenu(racine(a))) g = gauche(a) if not est_ABV(g): enfiler(f, g) d = droite(a) if not est_ABV(d): enfiler(f, d) return exploration_suivante(f)

11-C° Ecrire "si la file est vide ne fait rien, sinon fait quelque chose" est plutôt une mauvaise pratique mais elle permet de voir qu'il y a un cas de case (c'est vide) et un cas récursif.

Modifier la fonction pour avoir un code qui respecte les bonnes pratiques : comme il n'y a rien à faire dans le cas de base, on teste plutôt si on a le cas récursif directement.

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
def parcours_largeur_2(arbre:'AB') -> None: """Exploration (et affichage) en largeur de l'arbre (version récursive)""" if not est_ABV(arbre): f = nv_FV() enfiler(arbre, f) exploration_suivante(f) def exploration_suivante(f:'File') -> None: """Affiche la prochaine racine et stocke dans la File f les deux prochains sous-arbres détectés""": if not est_FV(f): # Cas récursif a = defiler(f) print(contenu(racine(a))) g = gauche(a) if not est_ABV(g): enfiler(f, g) d = droite(a) if not est_ABV(d): enfiler(f, d) return exploration_suivante(f)

5 - FAQ

Rien pour le moment

Dernière étape sur les arbres : d'autres implémentations possibles.

Activité publiée le 15 12 2020
Dernière modification : 31 01 2024
Auteur : ows. h.