IN 101 - Cours 12 1 1.1 Arbres Structure d’arbre Un arbre est une structure de donnée permettant de stocker des informations de manière hiérarchique. racine noeuds internes arc feuilles sous−arbre père Fils Frères Dans un arbre, des nœuds (dit parents) sont connectés à des des nœuds (dits fils) par des arcs. Les nœuds sans fils sont des feuilles. Les nœuds sans parent sont des racines. Dans un arbre, les arcs connectant les nœuds ne forment pas de peut être le parent de son parent). boucle (un nœud fils ne Dans un arbre, il n’y a pas de raccourci (chaque nœud a au plus un parent). Degré d’un nœud : nombre de fils. Arité d’un arbre : nombre maximal de fils. Arité 2: arbre binaire 1.2 Arité > 2: arbre n−aire Implémentation d’arbres Les arbres généraux peuvent être implantés en C en représentant un nœud par une structure contenant une liste chaı̂née de frères et chaque père a un pointeur sur son premier fils. 1 ld data chi struct node { i n t data ; struct node ∗ c h i l d ; struct node ∗ b r o t h e r ; }; brother d ild ch brother ch ild il ch brother brother Les arbres binaires peuvent être implémentés en représentant un nœud par une structure contenant un pointeur vers chaque fils. left data right struct bnode { i n t data ; struct bnode ∗ l e f t ; struct bnode ∗ r i g h t ; }; Les arbres binaires peuvent aussi être implémentés en utilisant un tableau dans lequel les fils d’un nœud d’indice i sont aux indices 2i + 1 et 2i + 2. Son père est à l’indice f loor((i − 1)/2). 2*0+1 2*0+2 a b d c e f 4*0+1 a b c d e f g 0 1 2 3 4 5 6 h 7 8 9 g h 1.3 Parcours d’arbre Parcourir un arbre en profondeur d’abord (DFS) consiste à récursivement explorer tous les les fils d’un nœud. Sur un arbre binaire ça consiste à explorer récursivement le sous-arbre fils droit puis le sous-arbre fils gauche (ou inversement). void d f s ( struct b node ∗n ) { i f ( n != NULL) { traitement ( optionnel ) 1 ; d s f ( n−> l e f t ) ; traitement ( optionnel ) 2 ; d s f ( n−>r i g h t ) ; traitement ( optionnel ) 3 ; } Trois parcours en profondeur possibles : préfixe (traitement 1), infixe (traitement 2), postfixe (traitement 3). Parcourir un arbre en largeur d’abord (BFS) consiste à parcourir ses nœud profondeur . On visite d’abord tous les nœuds de même profondeur. Le parcours en largeur d’abord s’appuie sur une structure de file. 2 par niveau de void l a r g e u r ( struct b node ∗n ) { enqueue ( n ) ; while ( ( n = t a k e ( ) ) != NULL) { d o s o m e t h i n g ( n−>data ) ; i f ( n−> l e f t != NULL) enqueue ( n−> l e f t ) ; i f ( n−>r i g h t != NULL) enqueue ( n−>r i g h t ) ; } } 0 1 2 / 3 4 5 6 7 1.4 Arbre binaire de recherche Un arbre binaire de recherche est tel que chaque nœuds contient une clef. La clef d’un nœud est > à celle de son fils gauche (donc à celles de tous les nœuds du sous-arbre gauche). La clef d’un nœud est < à celle de son fils droit (donc à celles de tous les nœuds du sous-arbre droit). < 21 > 21 21 7 1 42 35 10 64 > 42 8 22 38 > 21 et < 42 La recherche s’effectue par comparaison de la clef recherchée avec celle du nœud courant lors d’un parcours en profondeur d’abord. 35 ? 21 35 < 42 7 1 22 Présent 21 42 35 10 8 23 ? 35 > 21 38 23 < 42 7 64 1 10 8 23 > 21 23 < 35 23 > 22 22 bool { if if if ( n == NULL) return ( f a l s e ) ; ( v == n−>data ) return ( t r u e ) ; ( v < n−>data ) return ( s e a r c h ( v , n−> l e f t ) ) ; else return ( s e a r c h ( v , n−>r i g h t ) ) ; 42 35 s e a r c h ( i n t v , struct b node ∗n ) 64 38 } Absent La complexité des opérations de recherche, insertion, suppression dans un arbre binaire de recherche est généralement meilleure que dans les structures de tables . 3