Algorithmique P2 Les Arbres Renaud Dumont, Ulg 2009-2010 Biblio. supplémentaire Ouvrages ◦ Algorithmes et structures de données génériques, Divay M., 2004, Dunod ◦ Data Structures and Algorithm Analysis in C++, MA Weiss, 1998, Pearson Ed. Cours ◦ Cours d'algorithmique en langage C, Jean-Eric Pin, LIAFA, 1998 ◦ Algorithmique 4, Dominique Seret, Univ. Paris Descartes, 2008 ◦ Programmation avancée, T. Lecroq, Univ. Rouen ◦ Arbres de recherche, Sylvie Hamel, Université de Montréal, 2009 Graphes Un graphe est un couple G = (S, A) ◦ S est l'ensemble des sommets ◦ A est un sous-ensemble de S x S, l'ensemble des arêtes. arêtes ◦ A = {(1, 2), (1, 4), (2, 4), (3, 3), (4, 3)} Deux arêtes (s, t) et (s', t') sont consécutives si t = s' ◦ Arêtes consécutives (1, 2) et (2, 4) Graphes Un chemin dans un graphe est une suite d'arêtes consécutives. ◦ (1,2)(2,4)(4,3) est un chemin ◦ (1,4)(4,3)(3,3)(3,3) est un autre chemin ◦ … Graphe non dirigé (non orienté) : ◦ si (s, t) est une arête, (t, s) est une arête Arbres Arbre (libre) ◦ Graphe non-dirigé (non-orienté) non-vide, connexe et sans circuit (acyclique) Arbre enraciné ◦ Graphe non-dirigé muni d'un sommet distingué (la racine) racine et tel qu'il existe un chemin unique de la racine à un sommet quelconque. Arbres – Exemples d'utilisation Expression arithmétique ◦ ((a+b) * (c-d) – e) Chaine de caractères ◦ mais, mars, mer, mon Permet de mémoriser les caractères déjà rencontrés Arbres – Exemples d'utilisation Structure grammaticale Structure d'un livre, classifications biologiques, … Système de répertoires/fichiers d'un OS, interface fenêtrée d'un logiciel Un arbre, c'est une structure de données non linéaire permettant de hiérarchiser les données ◦ Relation inter-éléments = "est parent de" Arbres - Vocabulaire Nœud, racine, fils ◦ éventuellement qualifiés "à gauche" ou "à droite" pour les arbres binaires (voir suite) Nœud – Racine Nœud Fils (à gauche) Nœud Fils (à droite) Arbres - Vocabulaire Ancêtre, descendant, père, fils ◦ x descendant (propre) et fils (à droite) de y ◦ y ancêtre (propre) et père de x "propre" : si x est différent de y, tel qu'ici Tous les nœuds d'un arbre ont un et un seul parent, sauf la racine. r ◦ Propriété du chemin unique Frère, sœur ◦ Nœuds de même parent a b h y x Arbres - Vocabulaire Feuille = nœud sans fils Racine = le seul nœud sans père Degré d'un nœud = nombre de ses enfants Racine, Nœud interne r Feuille a Nœud interne y Nœud interne b Feuille b Feuille h Feuille x Arbres - Vocabulaire Profondeur d'un nœud = longueur du chemin entre la racine et ce nœud Hauteur d'un arbre = profondeur maximale de ses nœuds/hauteur de sa racine Hauteur d'un nœud = longueur maximale du chemin entre ce nœud et une feuille r Prof. = 0 Haut. = 2 H(Arbre) = 2 a Prof. = 1 Haut. = 0 y Prof. = 1 Haut. = 1 h Prof. = 2 Haut. = 0 x Prof. = 2 Haut. = 0 Arbres - Vocabulaire Niveau L dans un arbre = ensemble des nœuds de profondeur L Taille d'un arbre = nombre de ses nœuds r Prof. = 0 Niv. = 0 T(A) = 5 Niveau 0 contient 1 nœud Niveau 1 contient 2 nœuds Niveau 2 contient 2 nœuds a Prof. = 1 Niv. = 1 y Prof. = 1 Niv. = 1 h Prof. = 2 Niv. = 2 x Prof. = 2 Niv. = 2 Arbre enraciné Définition récursive ◦ Un nœud seul est un arbre dont la racine est ce nœud. ◦ Etant donnés un nœud r et k arbres T0,T1,…,Tk-1 ayant des racines notées respectivement r0,r1, …, rk-1, on construit un nouvel arbre de racine r en posant que r est le parent de r0,r1, …, rk-1. T0,T1,…,Tk-1 sont alors appelés les soussous-arbres de r dont les racines r0,r1, …, rk-1 sont les enfants de r. Arbre vide = Arbre ne contenant aucun nœud ◦ N'est pas considéré comme un arbre Arbres - Vocabulaire Quels sont les sous-arbres de l'arbre suivant ? A C B C B D D E F G D E E F F G G Le chemin C-E est-il sous-arbre de A ? Arbres ordonnés Un arbre ordonné est un arbre enraciné dans lequel tous les fils de chaque nœud sont ordonnés Arbres binaires Un arbre binaire est un ensemble fini de nœuds ◦ Vide (noté ε, qui n'est pas un arbre), ou ◦ Constitué d'une racine et de deux arbres disjoints Sous-arbre à gauche et sous-arbre à droite Dont l'un des deux est éventuellement vide Le degré d'un nœud d'un arbre binaire ne peut prendre que les valeurs 0, 1 ou 2 ◦ Chaque nœud possède 0,1 ou 2 fils. Arbres binaires On représente souvent un arbre binaire par le triplet A = (Ag, r, Ad) Pour l'arbre de gauche, il vient ◦ (Ø, 1,((Ø,3, Ø),2, Ø)) Et pour l'arbre de droite ? ◦ Rép. : ((Ø,2,(Ø,3, Ø)),1, Ø) Arbres binaires complets Un arbre binaire est complet si chaque niveau de l'arbre est complètement rempli Pour un nœud numéroté i, 1 ◦ Le fils à gauche est numéroté 2*i ◦ Le fils à droite 2*i+1 Propriétés : 2 4 3 5 6 7 ◦ Si H(A) = h, l'arbre possède n=2h+1-1 nœuds ◦ Le nombre de feuilles est égal au nombre de nœuds internes + 1 Arbres binaires Un arbre binaire est localement complet si tout nœud a 0 ou 2 fils Un arbre binaire est partiellement complet si toutes les feuilles sont placées sur la gauche de l'arbre Arbres binaires Un arbre est dégénéré (filiforme) si tous ses nœuds ont exactement 0 ou 1 fils (à droite ou au gauche) ◦ Un tel arbre de profondeur h possède h+1 noeuds Arbres binaires Arbres binaires de 1, 2, 3 et 4 nœuds Lesquels sont ◦ complets? ◦ localement complets ? Les arbres binaires Un arbre généalogique est-il un arbre binaire ? Si ascendant, oui Si descendant, non © JB Laurent Arbres binaires équilibrés Équilibré : Pour chaque nœud, les hauteurs des sous-arbres gauche et droit diffèrent d'au plus une unité Parfaitement équilibré : Pour chaque nœud, les nombres de nœuds de chaque sous-arbre gauche et droit diffèrent d'au plus une unité Equilibré Parfaitement Eq. Notions de parcours (∀arbres) Un parcours est une énumération des nœuds de l'arbre ◦ De par cette énumération, chaque parcours définit un ordre sur les nœuds On distingue ◦ les parcours de gauche à droite Le fils à gauche précède le fils à droite dans l'énumération ◦ les parcours de droite à gauche Le fils à droite précède le fils à gauche dans l'énumération Ensuite, on différencie ◦ Les parcours en largeur ◦ Les parcours en profondeur Parcours en largeur Dans un parcours en largeur, on énumère les nœuds par ordre croissant de profondeur des nœuds Autrement dit, de haut en bas, niveau par niveau (et de gauche à droite) Parcours en profondeur Parcours préfixe, préordre (NGD) : ◦ tout Nœud est suivi des nœuds de son sous-arbre Gauche puis des nœuds de son sous-arbre Droit Parcours infixe, symétrique (GND) : ◦ tout Nœud est précédé des nœuds de son sous-arbre Gauche et suivi des nœuds de son sous-arbre Droit Parcours suffixe, suffixe postfixe, postfixe, postordre (GDN) : ◦ tout Nœud est précédé des nœuds de son sous-arbre Gauche et des nœuds de son sous-arbre Droit On parle aussi d'ordre préfixe, infixe et suffixe On trouve aussi les parcours 'droite-gauche' Parcours en profondeur Soit l'arbre binaire suivant Parcours préfixe ◦ Nœud, Gauche, Droite ◦ a, b, d, e, h, c, f, i, g, k Parcours infixe ◦ Gauche, Nœud, Droite ◦ d, b, h, e, a, f, i, c, k, g Parcours suffixe ◦ Gauche, Droite, Nœud ◦ d, h, e, b, i, f, k, g, c, a Codage des arbres binaires Chaque arête d'un arbre binaire A est étiqueté ◦ Par 0 si f est un fils à gauche ◦ Par 1 si f est un fils à droite L'étiquette du chemin reliant la racine à un nœud donné est le mot formé par les étiquettes des arêtes le composant. Le code d'un arbre est l'ensemble des étiquettes des chemins issus de la racine Le code de l'arbre ci-contre est ◦ {ε, 0, 1, 00, 01, 10, 11, 010, 101, 110} ◦ Fournit un ordre de parcours des noeuds Codage de parcours préfixe Séquence : a,b,d,e,h,c,f,i,g,k Codes : ε, 0, 00, 01, 010, 1, 10, 101, 11, 110 Ordre lexicographique ◦ Soit un ordre sur un alphabet : 0<1, a<b<c<d… ◦ L'ordre lexicographique est défini par u <lex v ssi u est un préfixe de v, ou U=pau' et v=pbv' ou p est un mot, et a et b sont des lettres telles que a<b Codage de parcours suffixe Séquence : d,h,e,b,i,f,k,g,c,a Codes : 00,010,01,0,101,10, 110,11,1, ε Ordre opposé de l'ordre lexicographique obtenu en considérant 1<0 Étape s 1 a b d e h c f i g k Ordre lexicographique 2 ε 0 00 01 010 1 10 101 11 110 Code 3 ε 1 11 10 101 0 01 010 00 001 Complément du code 4 ε 0 00 001 01 010 1 10 101 11 5 a c g k f i b e h d Correspondance lignes 4-3-1 6 d h e b i f k g c a Ordre opposé Complément, ordre lex. Codage de parcours infixe Séquence :d,b,h,e,a,f,i,c,k,g Codes : 00,0,010,01,ε, 10,101,1,110,11 Ordre des nombres croissants On associe à chaque nœud son code concaténé à 1 Le code obtenu est considéré comme la partie fractionnaire d'un nombre entre 0 et 1 en binaire Nœud Code C.Frac. C.Frac. P.Frac. P.Frac. Ordre a ε .1 8/16 5 b 0 .01 4/16 2 c 1 .11 12/16 8 d 00 .001 2/16 1 e 01 .011 6/16 4 f 10 .101 10/16 6 g 11 .111 14/16 10 h 010 .0101 5/16 3 i 101 .1011 11/16 7 k 110 .1101 13/16 9 Codage de parcours en largeur Séquence : a,b,c,d,e,f,g,h,i,k Codes : ε, 0, 1, 00, 01, 10, 11, 010, 101, 110 Ordre croissant des mots croisés (shortlex) Défini par u<mc v ssi |u|<|v|, ou |u|=|v| et u <lex v Codage de parcours Exemple : (a+b)-(c*d) Arbre d'expression : Préfixe : Infixe : Postfixe : -+ab*cd a+b-c*d ab+cd*- Représentation paranthèsée Soit un parcours préfixe ◦ a, b, d, e, h, c, f, i, g, k Comment différencier les deux structures suivantes ? Représentation paranthèsée Comment spécifier la structure de l'arbre ? 1. Ecrire la paranthèse ouvrante puis l'étiquette du noeud 2. Descendre sur le premier fils et réappliquer 1. 3. Quand on ne sait plus descendre, on ferme la paranthèse, on remonte d'un niveau et on traite le fils suivant en réappliquant 1. 4. Une fois tous les fils traités, on ferme la paranthèse du noeud parent ◦ ◦ Ici, (a(b(d)(e(h)))(c(f(i))(g(k)))) Remarque : perte des distinctions fg ou fd dans un arbre binaire Représentation paranthèsée Exercices a b f c d e Réponses (a(b(d(e(h))))(c(f(i))(g(k)))) Et (a(b(c(d)(e))(f)(g))(h(i(j)(k)(l)(m)))) h g i j k l m Représentation d'un arbre en mémoire Soit l'arbre généalogique simplifié suivant Représentation par une liste de fils ◦ Difficulté pour ajouter des éléments (taille du tableau) Représentation d'un arbre en mémoire Allocation contiguë (mémoire ou fichier) ◦ Espace mémoire réservé à la compilation perte de place si grand nombre de fils pour un nœud ◦ Les pointeurs sont ici les indices des lignes du tableau Représentation d'un arbre en mémoire Représentation par allocation dynamique ◦ Calcul nécessaire du nombre de pointeurs de chaque nœud Pour un arbre généalogique, nombre difficile à préciser perte parfois importante d'espace mémoire ◦ Optimal pour un arbre dont les nœuds ont un degré constant (ex : binaire complet) Représentation d'un arbre en mémoire Solution : une liste de listes de nœuds À partir de MA Weiss, voir Sources supp. Représentation d'un arbre en mémoire Expression Tree ◦ Pile de pointeurs vers des arbres ◦ Exemple : ab+cde+** MA Weiss, voir Sources supp. Représentation d'un arbre en mémoire o Exemple : ab+cde+** MA Weiss, voir Sources supp.