Algorithmique et structures de données : examen de première session

Algorithmique et structures de données :
examen de première session
ENSIMAG 1A
Année scolaire 2008–2009
Consignes générales :
Durée : 3 heures. Tous documents et calculatrices autorisés.
Le barème est donné à titre indicatif. Il est sur 15 points, la note de chacun des 2 TP
étant ramenée sur 2.5 points.
Les exercices sont indépendants et peuvent être traités dans le désordre.
– La syntaxe Ada ne sera pas un critère déterminant de l’évaluation des copies. En
d’autres termes, les correcteurs n’enlèveront pas de point pour une syntaxe Ada in-
exacte, mais compréhensible (pensez à bien commenter votre code !).
Merci d’indiquer votre numéro de groupe de TD et de rendre votre copie
dans le tas correspondant à votre groupe.
Exercice 1 : B-arbres (10 pts)
Un B-arbre est une structure de données permettant d’implémenter un dictionnaire de
manière efficace. Il s’agit d’une structure hybride mêlant les structures d’arbres et de listes
(ou de tableaux). En effet, chaque nœud de l’arbre contient plusieurs clés du dictionnaire.
Un B-arbre peut être vu comme une généralisation d’un arbre binaire de recherche au
sens où les valeurs des clés stockées dans les nœuds le sont de manière imbriquée.
Un B-arbre de degré d,d2, est un arbre (pas forcément binaire) tel que :
1. chaque nœud xcomporte quatre informations :
un entier k1: le nombre de clés stockées dans ce nœud ;
une liste de kclés, généralement stockées par ordre croissant : cle1(x)cle2(x)
. . . clek(x);
un booléen EstF euille, indiquant si xest une feuille de l’arbre ou non ;
un pointeur pour chaque nœud fils de x, dans le cas où xn’est pas une feuille ;
2. le nombre de fils d’un nœud xest exactement k+ 1 (sauf bien sûr si xest une
feuille) ;
3. dk+ 1 2d, excepté pour la racine de l’arbre qui peut avoir moins de dfils ;
4. les valeurs des clés d’un nœud xet les valeurs des clés de ses fils sont intercalées, voir
figure 1 pour un exemple : les clés du premier fils de xont des valeurs inférieures
à la valeur de la première clé de x, les clés du deuxième fils de xont des valeurs
comprises entre les valeurs de la première et de la deuxième clés de x, etc. ;
1
5. les feuilles sont toutes situées à la même hauteur dans l’arbre, c’est-à-dire au dernier
niveau.
La figure 1 montre un exemple de B-arbre.
Fig. 1 – Exemple d’un B-arbre.
L’objectif de cet exercice est d’étudier comment implémenter les trois opérations stan-
dards que sont la recherche, l’insertion et la suppression d’une clé pour cette structure de
données.
1 Questions générales
Question 1 Pour quel(s) degré(s) dl’arbre de la figure 1 est-il un B-arbre valide ?
Justifier.
Pour d= 2 ou 3, car chaque nœud, exceptée la racine, possède 2 ou 3 clés, donc d12
et 32d1.
Question 2 Dessiner les quatre B-arbres de degré supérieur ou égal à 2et dont les clés
ont les valeurs { 1, 2, 3, 4, 5 }.
On ne peut pas placer 3 clés ou plus à la racine, à cause de la deuxième règle de la
définition et car on n’a que 5 clés.
Si on place 2 clés à la racine : une seule solution, placer 2et 4et avoir 3 fils ayant chacun
une clé (1,3et 5).
Si on place 1 clé à la racine : on peut placer 2,3ou 4, et dans les trois cas on a 2 fils. Le
fils gauche a pour clé(s) :
1dans le premier cas ;
1et 2dans le deuxième cas ;
1,2et 3dans le troisième cas.
Le fils droit a pour clé(s) :
3,4et 5dans le premier cas ;
2
4et 5dans le deuxième cas ;
5dans le troisième cas ;
Question 3 Définir, en Ada, un type B-Arbre. On suppose connus la valeur (fixe) de d
et le type Cle.
Il faut d’abord définir le type ListeCles :
type ElemCle;
type ListeCle is access ElemCle;
type ElemCle is record
Val: Cle;
Suiv: ListeCle;
end record;
Les pointeurs vers les fils peuvent être stockés de différentes façons, par exemple dans une
liste :
type Fils;
type ListeFils is access Fils;
type Fils is record
Val: B-Arbre;
Suiv: ListeFils;
end record;
Le type B-Arbre est un pointeur vers un nœud de l’arbre :
type Noeud;
type B-Arbre is access Noeud;
type Noeud is record
K: Integer;
LesCles: ListeCle;
EstFeuille: Boolean;
LesFils: ListeFils;
end record;
Question 4 Soit nle nombre de clés d’un B-arbre de degré d, et hsa hauteur. Montrer
que
hlogd
n+ 1
2(1)
On rappelle que la hauteur de l’arbre vide est fixée à 1.
Par définition, la racine contient au moins une clé et les autres nœuds au moins d1
chacun. On a donc au moins deux nœuds au niveau 1,2dau niveau 2,2d2au niveau 3,
3
etc. Le nombre total de nœuds est donc
n1+(d1)
h
X
i=1
2di1= 1 + 2(d1)dh1
d1= 2dh1
On obtient donc bien
logd
n+ 1
2h
2 Recherche d’une clé
On s’intéresse dans cette partie à la recherche d’une clé dans un B-arbre.
Question 5 Décrire en français le principe d’un algorithme récursif de recherche d’une
clé dans un B-arbre.
Parcourir la liste des clés du nœud courant (évidemment, on part de la racine), tant
qu’elles sont inférieures à la clé recherchée : si on trouve la clé on s’arrête, sinon on
appelle récursivement l’algorithme avec le fils du nœud courant correspondant au bon
intervalle de valeurs de clés. Si le nœud courant est une feuille et qu’on n’a pas trouvé la
clé, on stoppe la recherche.
Question 6 Ecrire la procédure Ada Recherche(A : in B-Arbre ; C : in Cle ; A’ :
out B-Arbre ; I : out Integer) qui implémente cet algorithme.
Cette fonction renvoie à la fois un pointeur vers le nœud contenant la clé recherchée et un
entier indiquant la position de la clé dans la liste des clés stockées en ce nœud (exemple : la
recherche de la clé 8dans l’arbre de la figure 1 renvoie un pointeur vers le nœud contenant
les clés 7,8et 9, ainsi que l’entier 2). Si la clé recherchée n’est pas présente dans l’arbre,
la fonction renvoie le pointeur NULL ainsi qu’un entier quelconque.
procedure Recherche(A: in B-Arbre; C: in Cle; A’: out B-Arbre; I: out Integer) is
MesCles : ListeCle;
MesFils : ListeFils;
J : Integer := 1;
begin
I := 1;
-- Parcours de la liste des clés du noeud courant
MesCles := A.LesCles;
while I <= A.K and then MesCles.Val < C loop
-- remarque : on peut remplacer la première condition par MesCles != NULL
I := I+1;
MesCles := MesCles.Suiv;
4
end loop;
if I <= A.K and then MesCles.Val = C then
-- Si la clé est trouvée, c’est fini
A’ := A;
elsif EstFeuille then
-- Si la clé n’est pas trouvée et que le noeud courant est une feuille, c’est fini aussi
A’ := NULL;
else
-- Sinon, appel récursif avec le bon fils
MesFils := A.LesFils;
while J < I loop
MesFils := MesFils.Suiv;
end loop;
Recherche(MesFils.Val,C,A’,I);
end if;
end Recherche;
Question 7 Quel est le coût asymptotique en pire cas de cet algorithme, en fonction de
net de d?
Indication : utilisez la relation (1) de la question 4.
En pire cas on parcourt l’arbre de la racine vers une feuille, et pour chaque nœud atteint
on parcourt la liste des clés. On sait qu’on a au pire 2d1clés, le coût est donc (2d1)h,
ce qui nous donne un O(dlogdn).
3 Insertion d’une clé
L’insertion d’une clé dans un B-arbre est assez complexe, car il y a de nombreuses pro-
priétés à conserver. La figure 2 montre un exemple de mise à jour d’un B-arbre de degré
3lors de l’insertion successive de quatre clés.
Comme pour un arbre binaire de recherche, l’insertion se fait en cherchant à partir de la
racine la feuille où ajouter la clé, en fonction des valeurs des clés des nœuds traversés.
Dans le cas où la feuille où on souhaite insérer la clé est complète, c’est-à-dire qu’elle
contient déjà 2d1clés, il faut “séparer” cette feuille en deux. Cette séparation se fait en
remontant la clé médiane vers le nœud père puis en remplaçant la feuille par deux feuilles
contenant chacune d1clés (respectivement les plus petites et les plus grandes), voir
la figure 3 pour un exemple. La nouvelle clé est ensuite insérée dans la feuille adéquate.
Mais le problème peut alors se propager : le nœud père peut devenir complet à son tour.
Afin de remédier à ce problème, les nœuds complets sont systématiquement séparés (de
la même manière) lors de la traversée à partir de la racine.
La procédure globale peut s’écrire de la manière suivante :
5
1 / 12 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !