• Aucun résultat trouvé

Les arbres

3.5 ARBRES N-AIRES ORDONNÉS ÉQUILIBRÉS : LES B-ARBRES

3.5.3 Recherche, parcours, destruction

3.5.3.a Recherche d’un élément : accès direct

Il s’agit d’accéder directement à un élément du B-arbre. Le parcours de l’arbre n-aire ordonné permet de retrouver facilement une valeur par descente récursive dans un des sous-arbres. La valeur peut se trouver dans un nœud intermédiaire ou dans une feuille. Si on atteint une feuille sans trouver la valeur cherchée c’est que la valeur n’est pas dans l’arbre.

3.5.3.b Parcours des éléments : accès séquentiel

Il s’agit d’énumérer toutes les valeurs du B-arbre. Le parcours ressemble au parcours de l’arbre binaire, mais cette fois, il y a (sauf pour la racine) de N+1 à 2N+1 sous-arbres qu’il faut parcourir récursivement.

void parcoursBArbre (PNoeud racine) { if (racine != NULL) {

parcoursBArbre (racine->p0);

for (int i=0; i<racine->nbE; i++) { printf ("%s ", racine->elt [i].cle);

parcoursBArbre (racine->elt [i].p);

} } }

5 9

10 11 15 16

7 8

1 2 27 35 42 47

23 40 12

9 12 23 40

15 16 27 35

10 11

1 2 7 8 42 47

Figure 108 Insertion de 5 ; éclatement de 1.2.7.8, puis de 9.12.23.40.

04Chap_03 Page 185 Samedi, 17. janvier 2004 10:37 10

186 3 Les arbres

3.5.3.c Destruction d’un élément

La destruction d’un élément est a priori simple. Il faut localiser le nœud où se trouve la clé et l’enlever. Cependant, si la clé est dans un nœud non feuille, le retrait de la clé va poser des problèmes pour accéder aux valeurs du sous-arbre qui avaient été rangées en fonction de cette valeur disparue. Il faut la remplacer par soit la plus grande valeur du sous-arbre à gauche de la valeur retirée, soit par la plus petite du sous-arbre à droite (voir § 3.3.2.d, page 161 : suppression dans un arbre ordonné). Si pour un nœud le nombre de valeurs devient inférieur à N et si une des pages voisines (gauche ou droite) a plus de N valeurs, il y a redistribution entre ces 2 pages, sinon les 2 nœuds (le nœud courant et celui de droite par exemple) sont regroupés et un des nœuds est détruit. La valeur médiane est recalculée.

Exercice 20 - Gestion d’un tournoi à l’aide d’une liste d’arbres (voir § 3.1.2.e, page 105)

On souhaite développer un logiciel qui permette d’enregistrer et de consulter les résultats d’un tournoi. À partir de ces résultats enregistrés dans un fichier séquentiel, on construit une liste d’arbres mémorisant les différents matchs joués. À la fin du tournoi, la liste ne contient plus qu’un seul élément qui pointe sur la racine de l’arbre des matchs. Cette racine contient des informations sur le match de finale. On désire également répondre à des interrogations sur les résultats des matchs déjà enregistrés.

La construction de la liste d’arbres est schématisée sur les exemples suivants :

• un seul match joué, le fichier séquentiel contient : b,a b a gagné contre a

• après enregistrement de : b,a b a gagné contre a c,d c a gagné contre d

li

/ /

b a / /

li

/ /

b a / / c d / /

04Chap_03 Page 186 Samedi, 17. janvier 2004 10:37 10

3.5 • Arbres n-aires ordonnés équilibrés : les b-arbres 187

© Dunod – La photocopie non autorisée est un délit.

• après enregistrement de : b,a ; c,d ; b,c ; h,g ; f,e ; h,f ;

• après enregistrement de tous les résultats du tournoi b,a ; c,d ; b,c ; h,g ; f,e ; h,f ; b,h, il ne reste plus qu’un seul arbre dans la liste.

Les schémas précédents n’indiquent pas les détails de l’implémentation d’un noeud de l’arbre. Le schéma de droite de la Figure 110 indique l’implémentation réelle du noeud schématisé à gauche.

Soient les déclarations suivantes :

#include "liste.h"

#include "arbre.h"

#define LGMAX 20

typedef char Chaine [LGMAX+1]; // 0 de fin typedef struct {

Chaine joueur1; // gagnant = joueur1 Chaine joueur2;

} Match;

Écrire les fonctions suivantes de consultation de l’arbre :

• void listerRestants (Liste* li) ; qui liste les joueurs de la liste li non encore éliminés.

li

/ /

b c h f

b a / / c d / / h g / / f e / /

Figure 109 Une liste d'arbres.

b a

b a

Figure 110 Détail de l'implémentation d'un nœud.

04Chap_03 Page 187 Samedi, 17. janvier 2004 10:37 10

188 3 Les arbres

• void listerArbres (Liste* li, int type) ; qui effectue le récapitulatif des matchs en listant le contenu de chacun des arbres de la liste li. Le parcours est préfixé si type=1, postfixé si type=2. Un dessin des arbres est donné si le type=3. Les résultats attendus des parcours préfixé et postfixé de l’arbre de l’exemple sont donnés ci-dessous.

• void listerMatch (Noeud* pNom, Chaine joueur) ; qui à partir d’un pointeur pNom sur le dernier match enregistré pour un joueur donné, fournit la liste des matchs que ce joueur a disputés

• void listerMatch (Liste* li, Chaine joueur) ; qui recherche joueur dans la liste li des arbres, et fournit la liste des matchs de joueur.

Écrire les fonctions suivantes de création de l’arbre :

• void enregistrerMatch (Liste* li, Chaine j1, Chaine j2) ; qui enregistre le match gagné par j1 contre j2 dans la liste li des arbres.

• void creerArbres (FILE* fe, Liste* li) ; qui crée la liste li des arbres à partir du fichier séquentiel fe. Cette fonction utilise enregistrerMatch().

Faire un programme correspondant au menu suivant : GESTION D'UN TOURNOI

0 - Fin

1 - Création de la liste d'arbres à partir d'un fichier 2 - Enregistrement d'un match

3 - Liste des joueurs non éliminés 4 - Parcours préfixé des arbres 5 - Parcours postfixé des arbres 6 - Dessins des arbres des matchs 7 - Liste des matchs d'un joueur Exemples de résultats (choix 4) :

PARCOURS DE L'ARBRE préfixé indenté : b gagne contre h b gagne contre c b gagne contre a c gagne contre d h gagne contre f h gagne contre g f gagne contre e

04Chap_03 Page 188 Samedi, 17. janvier 2004 10:37 10

3.5 • Arbres n-aires ordonnés équilibrés : les b-arbres 189

© Dunod – La photocopie non autorisée est un délit.

Exemples de résultats (choix 5) : postfixé indenté :

b gagne contre a c gagne contre d b gagne contre c h gagne contre g f gagne contre e h gagne contre f b gagne contre h

matchs du joueur e f gagne contre e

Un exemple du dessin d’une liste de deux arbres de jeu (choix 6).

dessins des arbres des matchs

| | _________Guillaume:Ronan_______

| | | | Guillaume:Nicolas Ronan:Thomas

| | _______Vincent:Julien_______

| | | | Vincent:Gilles Julien:Alain Exercice 21 - Mémorisation d’un dessin sous forme d’un arbre binaire

(allocation contiguë, voir Figure 75, page 150)

Une image peut être représentée par un tableau à deux dimensions de booléens si l’image est en noir et blanc. Une autre méthode plus économique en mémoire dans certains cas (tracés continus) est de ne représenter que les points significatifs, sous forme d’un arbre, et de restituer l’image à partir de cet arbre. On peut de plus très facilement faire varier la taille du dessin. Sur la Figure 111, le premier dessin repré-sente un caractère 1 manuscrit. Le deuxième dessin schématise ce caractère sous

04Chap_03 Page 189 Samedi, 17. janvier 2004 10:37 10

190 3 Les arbres

forme d’un arbre n-aire. Il faut tracer le segment 0, puis en partant de la fin du segment 0, il faut tracer le segment 1 et le segment 2. De même, en partant de la fin du segment 2, il faut tracer les segments 3, 4 et 5. Le troisième dessin représente l’arbre n-aire converti sous sa forme binaire équivalente. Les segments sont décrits avec un code indiquant la direction de déplacement (1:nord, 2:nord-est, 3:est, 4:sud-est, 5:sud, 6:sud-ou4:sud-est, 7:ou4:sud-est, 8:nord-ouest).

La description des différents segments est enregistrée dans le tableau desc.

L’arbre binaire est mémorisé en allocation contiguë dans le tableau arbre. Les struc-tures de données utilisées sont les suivantes :

#include "ecran.h"

#define NULLE -1 typedef int PNoeud;

typedef struct {

int indice; // indice sur desc []

PNoeud gauche;

PNoeud droite;

} Noeud;

int desc [] = { // description de l'image // 0 15 3, 5, 5, 5, 3, 6, 6, 6, 7, 5, 5, 5, 5, 5, 5, 5, 3, 7, 7, 7, 3, 3, 3, 3, 2, 5, 5

};

Noeud arbre [] = { // l'arbre représentant l'image { 0, 1, -1 }, // 0

{ 4, -1, 2 }, // 1 { 8, 3, -1 }, // 2 { 16, -1, 4 }, // 3 { 20, -1, 5 }, // 4 { 24, -1, -1 } // 5 };

0

1

2

3 4

5

0

1 2

3 4 5

0

1

2 3

4

5 Figure 111 Mémorisation d'un tracé graphique sous forme d'arbre.

04Chap_03 Page 190 Samedi, 17. janvier 2004 10:37 10