Telechargé par Youssef Mcheik

tpnote

publicité
Année 2021/2022 - L2 Informatique, UE 4TIN402U
Algorithmique des structures de données arborescentes
TP Noté - 19 Avril 2022
Durée 1h20mn - Aucun document papier autorisé
Collège
Sciences et
Technologies
Implémentation des Arbres vert-noirs
Le sujet consiste à implémenter plusieurs procédures sur les arbres verts-noirs que nous avons vus en DS. En
particulier, on va implémenter l’algorithme d’insertion.
Important : Corrigé du DS disponible en ligne
Certaines des fonctions demandés sont l’implémentation d’algorithmes vus dans le DS. Le corrigé de ce même DS
est disponible sur Moodle et vous pouvez le consulter.
Consignes
Le rendu s’effectue sur Moodle :
— Chaque exercice correspond a un rendu Moodle différent (auto-évalué, vous pouvez faire des tests).
— Vous devez également soumettre un fichier récapitulatif contenant toutes vos fonctions.
Partie 1 : Définition
On commence par rappeler la définition des arbres vert-noirs. Le texte est essentiellement repris du DS. On introduit
en même un type OCaml pour les représenter.
Arbres binaires colorés. Un arbre binaire coloré est un arbre binaire dans lequel chaque nœud est colorié soit avec la
couleur noire, soit avec la couleur vert. On donne un exemple dans la Figure 1 ci-dessous.
6
3
8
5
1
9
Figure 1 – Un arbre binaire coloré contenant six nœuds : trois sont noirs et trois sont verts
On rappelle que les représentent un arbre vide : ce ne sont pas des nœuds. Pour tout arbre binaire coloré t, on
note h(t) sa hauteur (par convention, la hauteur de l’arbre vide est “−1”) et s(t) sa taille (son nombre total de nœuds).
On définit deux types OCaml qu’on va utiliser pour représenter les arbre coloré. Le premier sert à coder les couleurs
(vert et noir), et le second les arbres colorés eux-mêmes :
1
2
type c o l o r = Green | Black
type ’ a c t r e e = Empty | Node of C o l o r ∗ ’ a ∗ ’ a c t r e e ∗ ’ a c t r e e
Arbres vert-noirs. On définit une mesure spécifique aux arbres binaires colorés. Pour chaque branche d’un arbre
binaire coloré t, la hauteur noire de cette branche est le nombre de nœuds noirs qu’elle contient. Enfin, la hauteur noire
de l’arbre coloré t, notée hn(t), est le maximum parmi les hauteurs noires de toutes ses branches. Par exemple, l’arbre t
de la Figure 1, contient des branches dont les hauteurs noires sont 1, 2, et 3. Il a donc lui-même pour hauteur noire
hn(t) = 3. On notera que par définition, la hauteur noire de l’arbre vide est hn( ) = 0.
Définitions des arbres verts-noirs
Les arbres vert-noirs sont des arbres binaires colorés spéciaux (en particulier, ce sont des ABRs). Plus précisément,
un arbre vert-noir est un arbre binaire coloré t qui satisfait les trois conditions suivantes :
(a) t est un arbre binaire de recherche.
(b) Pour tout nœud x de t, si g est le sous-arbre gauche de x et d est son sous-arbre droit, alors hn(g) = hn(d)
(en d’autres termes, g et d ont la même hauteur noire).
(c) Tous les nœuds verts de t sont soit sa racine, soit le fils gauche d’un nœud noir.
On donne un exemple dans la Figure 1 ci-dessous (à l’inverse, l’arbre coloré de la Figure 1, n’est pas vert-noir)
7
4
2
9
6
8
Figure 2 – Un arbre vert-noir
Fonction 1
Test des propriétés d’un arbre vert-noir
Écrire une fonction is_greenblack : ’a ctree −> bool qui prend en entrée un arbre coloré et retourne true si
celui-ci est vert-noir et false sinon. Attention, la fonction devra tester les trois propriétés dans la définition (en
particulier, il faut tester si l’arbre pris en entrée est un ABR).
Remarque : Pour cette question et toutes les suivantes, vous avez le droit de réutiliser/modifier
des fonctions que vous avez codé lors des TP au cours du semestre.
Partie 2 : Insertion
On va maintenant se concentrer sur l’implémetation de l’insertion dans les arbres vert-noirs. Comme vu dans le DS,
la procédure est basée sur une notion intermédiaire : les arbres quasi -vert-noirs. Commençons par rappeler la définition.
De façon informelle, un arbre quasi-vert-noir est un arbre coloré qui a des propriétés moins fortes qu’un “vrai” arbre
vert-noir : il satisfait les deux premières conditions dans la définition des arbres vert-noirs, mais il peut contenir au plus
un nœud vert qui ne satisfait pas la troisième condition.
Définitions des arbres quasi-verts-noirs
Un arbre quasi-vert-noir est un arbre binaire coloré t qui satisfait les trois conditions suivantes :
(a) t est un arbre binaire de recherche.
(b) Pour tout nœud x de t, si g est le sous-arbre gauche de x et d est son sous-arbre droit, alors hn(g) = hn(d)
(en d’autres termes, g et d ont la même hauteur noire).
Fonction 2
(c) Il existe au plus un nœud vert de t qui n’est ni la racine, ni le fils gauche d’un nœud noir.
Test des propriétés d’un arbre quasi-vert-noir
Écrire une fonction is_quasigreenblack : ’a ctree −> bool qui prend en entrée un arbre coloré et retourne
true si celui-ci est quasi-vert-noir et false sinon.
Rappel : Corrigé du DS disponible en ligne
Le corrigé peut se montrer utile pour les trois questions qui vont suivre.
On reprend maintenant les arbres quasi-vert-noirs élémentaires. On rappelle que les trois premiers types sont les
suivants :
c
b
a
c
a
t4
t3
a
t4
b
t1
b
t1
t2
t3
Type 3
t1
t2
t2
Type 1
t3
Type 2
Figure 3 – Arbres quasi-vert-noirs de rang 1, 2 et 3.
Fonction 3
Réparation d’un quasi-vert-noir de type 1, 2 ou 3
Écrire une fonction qgb_repair123 : ’a ctree −> ’a ctree qui prend en entrée un arbre coloré t. Si l’arbre t
est quasi-vert-noir de type 1,2 ou 3, la fonction devra retourner un “vrai” arbre vert-noir contenant le même
ensemble de clés et de même hauteur noire. Dans tous les autres cas, le fonction devra simplement retourner t
lui-même. On demande ici une fonction dont la complexité est constante.
On rappelle que les deux autres types sont les suivants :
a
b
a
b
t1
t2
t3
Type 4
t1
t3
t2
Type 5
Figure 4 – Arbres quasi-vert-noirs de rang 4 et 5
Fonction 5
Fonction 4
Réparation d’un quasi-vert-noir de type 4 ou 5
Écrire une fonction qgb_repair45 : ’a ctree −> ’a ctree qui prend en entrée un arbre coloré t. Si l’arbre t est
quasi-vert-noir de type 4 ou 5, la fonction devra retourner un “vrai” arbre vert-noir contenant le même ensemble
de clés et dont la hauteur noire a été incrémentée de “1”. Dans tous les autres cas, le fonction devra simplement
retourner t lui-même. On demande ici une fonction dont la complexité est constante.
Insertion dans un arbre vert-noir
Écrire une fonction qgb_insert : ’a ctree −> ’a −> ’a ctree qui prend en entrée un arbre vert-noir t et une
clé k. Elle doit retourner un nouvel arbre vert-noir obtenu en insérant la clé k dans t. Vous pouvez (devez) bien
sûr utiliser les fonctions des deux exercices précédents comme sous-procédure.
Partie 3 : Création d’arbres vert-noirs
Fonction 6
On veut maintenant utiliser notre fonction d’insertion pour créer des arbres vert-noirs. On va d’abord commencer
par la création à partir d’une liste.
Création d’un arbre vert-noir à partir d’une liste
Écrire une fonction list_to_gb : ’a list −> ’a ctree qui prend en entrée une liste et retourne un arbre vert-noir
dont les clés sont exactement les éléments présents dans la liste (si celle-ci contient un élément deux fois ou
plus, on ne garde qu’un seule copie).
On cherche maintenant à convertir un arbre coloré quelconque en arbre vert-noir. Pour cela, on va écrire une fonction
qui convertit un arbre en liste (il suffit de combiner cette fonction avec celle de l’exercice précédent). On demande deux
versions. La première est simple mais peu efficace car elle utilise la concaténation de listes.
Fonction 7
Liste des étiquettes d’un arbre (version lente)
Écrire une fonction get_keys : ’a ctree −> ’a list qui prend en entrée un arbre coloré et retourne la liste des
clés qu’il contient dans l’ordre infixe.
L’ordre infixe est défini récursivement. Si l’arbre est vide, la liste de ses clés est vide. Sinon, on commence
par lister les clés dans le sous-arbre gauche, puis celle qui étiquette la racine, et enfin celles qui se trouvent dans
le sous-arbre droit. Par exemple sur l’arbre de la figure 2, la liste obtenue est [2; 4; 6; 7; 8; 9].
Dans cette version, on pourra utiliser l’opérateur “@” de concaténation de listes.
Fonction 8
Transformation en un arbre vert-noir (version rapide)
Écrire une fonction get_keys_fast : ’a ctree −> ’a list qui prend en entrée un arbre coloré et retourne la liste
des clés qu’il contient dans l’ordre infixe sans utiliser la concaténation de liste.
On pourra utiliser une fonction auxiliaire get_keys_forest : ’a ctree list −> ’a list qui prend en entrée
une liste d’arbre colorés a retourné la liste des clés des arbres contenus dans celle-ci dans l’ordre infixe.
Fonction 9
Pour finir on va utiliser les arbres vert-noirs pour programmer un tri.
Tri vert-noir
Écrire une fonction gb_sort : ’a list −> ’a list qui prend en entrée une liste et retourne une version triée de
celle-ci en ayant éliminé les copies multiples d’une même clé.
La fonction devra être écrite en combinant celles des exercices précédents.
Téléchargement