TD n 2

publicité
Université Paris Diderot – Paris 7
L3 Informatique
Algorithmique
Année 2010-2011, 1er semestre
TD n◦2
Arbres Binaire de Recherche
Le type de donné “arbre" sera utilisé pour indiquer l’ensemble de toutes les Arbres Binaires Étiquetés
(ABEs) par des clés de type entier. La taille de un ABE a est par définition le nombre de clés contenues
dans a. Nous rappelons que un Arbres Binaire de Recherche (ABR) a est un ABE tel que tout nœud
interne b de a contient un clé
– supérieure ou égale à toutes le clés contenues dans le sous-arbre gauche de b ;
– inférieure strictement à toutes le clés contenues dans le sous-arbre droit de b.
Exercice 1 Est-ce que on peut utiliser la procédure suivante pour tester si un ABE a est un ABR ?
1
2
3
4
Fonction estABR(a : arbre) : booléen
début
si (estVide(a)) alors
retourner vrai;
si (estVide(G(a))) alors
gauche := clé(a);
5
6
sinon
gauche := clé(G(a));
7
8
si (estVide(D(a))) alors
droite := clé(a);
9
10
sinon
droite := clé(D(a));
11
12
retourner (gauche ≤ clé(a) ≤ droite ∧ estABR(G(a)) ∧ estABR(D(a)));
13
14
fin
Sinon écrivez une fonction qui teste si un ABE a est un ABR.
Pour un tableau A[1, . . . , n] la définition de “k-ème élément" est très simple à comprendre et l’accès au
k-ème élément est une opération élémentaire (c’est à dire, avec complexité Θ(1)). Au contraire un arbre
binaire n’est pas une structure linéaire et nous pouvons definire plusieur notions de “k-ème élément",
selon la facon dans laquelle nous parcourons l’arbre.
1
Étant donné un ABE quelconque on choisit la façon suivante de numéroter les nœuds de l’arbre :
Fig. 1 – Numérotation des nœuds d’un ABE
Exercice 2 [Accès au k-ème élément] Soit a un ABR.
Question 1. Proposez une méthode pour retourner le k-ème élément de a en utilisant :
– une procédure VisiteGRD(a : arbre) qui parcourt complètement l’arbre a.
– un tableau d’entiers T .
Quelle est la complexité de cette méthode en fonction de la taille de a ?
Question 2. En supposant d’avoir à disposition le type de donnée booléen × entier, proposez une
fonction RecherchePos(a : arbre, n : entier) : booléen×entier telle que si (b, k) = RecherchePos(a, n)
alors
– si la taille de a est inférieure à n alors b = faux et k est la taille de a ;
– si la taille de a n’est pas inférieure à n alors b = vrai et k est la valeur de la k-ème clé.
Quelle est la complexité de cette méthode ?
Question 3. En supposant qu’on dispose d’une fonction taille(a : arbre) : entier calculant la taille
d’un arbre a en Θ(1), proposez une fonction RecherchePos(a : arbre, k : entier) : arbre telle que si
b = RecherchePos(a, k) alors
– si taille(a) < n, alors b = ArbreVide() ;
– si taille(a) ≥ n, alors clé(b) est la k-ème clé dans l’arbre a.
Évaluez la complexité de la procédure en fonction de la hauteur de l’arbre a.
Question 4. En acceptant de modifier légèrement la structure des ABRs, pouvez-vous proposer une
fonction taille(a : arbre) : entier ayant complexité Θ(1) ? Vérifierez que votre modification ne change
pas la complexité des fonctions d’insertion et de suppression d’un nœud dans un ABR.
Exercice 3 [Recherche du successeur] Modifiez légèrment la définition de ABR de telle sorte que
toutes les clés soyent distinctes. On appelle strict un ABR qui satisfait cette définition. Soit a un ABR
strict. Le successeur de un nœud x (s’il existe) est par définition le nœud y ayant la plus petit clé entre
le clés plus grand que clé(x).
Question 1. Montrer rigoureusement que dans a :
(a) l’élément minimum se trouve à un nœud sans fils gauche.
(b) si un nœud a un fils droit, son successeur est le minimum de son sous arbre droit. En déduire que
si un nœud a un fils droit, alors son successeur n’a pas de fils gauche.
(c) si un nœud n’a pas de fils droit, son successeur, s’il existe, est le premier de ses ancètres dont le fils
gauche est aussi l’un de ses ancètres.
Question 2. Écrire une fonction succ(b : arbre) : arbre qui retourne le sous arbre de a dont la racine
est le successeur de b. Quelle est la complexité en temps de cet algorithme ?
2
Exercice 4 Soit a un ABR strict, soient x un nœud feuille et y son parent. Montrer que clé(x) est soit
la plus petite clé de a supérieure à clé(y), soit la plus grande clé de a inférieure à clé(y).
Exercice 5 On peut trier un tableau T de nombres entiers en commençant par construire par insertions
successives un ABR contenant ces nombres puis en effectuant un parcours infixe de l’arbre. Quels sont
les temps d’exécution de cet algorithme en fonction de la taille de T dans le pire et dans le meilleur des
cas ?
Exercice 6 [Insertion à la racine] Dans un arbre binaire de recherche, avec la méthode d’insertion
classique, toutes les nouvelles valeurs sont placées aux feuilles de l’arbre. Si l’on souhaite accéder à un
nœud inséré récemment dans l’arbre, il faudra parcourir toute la hauteur de l’arbre. Dans certaines
applications, on souhaite accéder plus fréquemment aux derniers éléments insérés. Il s’agit du principe
LRU 1 . Dans ce cas particulier, il peut être intéressant d’insérer à la racine. En procédant de la sorte, les
valeurs auxquelles on souhaite accéder le plus souvent ont plus de chance d’être à une faible profondeur.
En considérant l’exemple de la figure ?? :
Question 1. Tracez le chemin qui va de la racine au nœud où classiquement il faudrait insérer le nœud
33.
Question 2. À partir des réponses aux questions précédentes, proposez une procédure insertionRacine(a :
arbre, k : entier) d’insertion à la racine dans un ABR.
Évaluer la complexité de cet algorithme dans le pire des cas.
Fig. 2 – un arbre binaire de recherche
1 pour
Least Recently Used !
3
Téléchargement