Structures de données avancées - Master informatique

publicité
Structures de données avancées
Master d’Informatique — UPMC
STL - M1.
UE Algorithmique avancée
Semaines 1 à 3
1
Année 2006 — 2007
Ordres de grandeur
1. Rappeler la définition de O, Θ, Ω et o.
2. Montrer que :
• si f ∈ O(g) alors O(f ) ⊆ O(g) et O(max(f, g)) = O(g)
• O(f + g) = O(max(f, g)).
3. Ranger dans l’ordre
: O(n log n), O(2 n ), O(log n), O(1), O(n2 ), O(n3 ) et O(n).
Pn croissant
k
k+1
4. Montrer que :
).
p=1 p ∈ Θ(n
2
Coût amorti
Exercice 1 On considère les deux opérations fondamentales sur les piles : Empiler(S,x) et
Depiler(S), auxquelles on ajoute l’opération MultiDepiler(S,k). L’opération MultiDepiler(S,k)
retire les k premiers objets du sommet de la pile si la pile contient au moins k objets et vide la
pile sinon.
1. Calculer le coût amorti d’une opération en utilisant la méthode par agrégat.
2. Même question en utilisant la méthode du potentiel.
Exercice 2 Aux trois opérations : Empiler(S,x), Depiler(S) et MultiDepiler(S,k), définies
sur les piles, on ajoute l’opération MultiEmpiler(S,x1,x2,...,xk), qui permet d’empiler les
objets x1, x2, ..., xk sur la pile.
1. En utilisant la méthode par agrégat, calculer le coût amorti d’une opération dans chacun
des cas suivants :
• dans l’opération MultiEmpiler(S,x1,x2,...,xk), le nombre d’objets que l’on peut
empiler est borné par une constante c
• dans l’opération MultiEmpiler(S,x1,x2,...,xk), le nombre d’objets que l’on peut
empiler est inférieur ou égal au nombre d’objets de la pile S.
2. Même question en utilisant la méthode du potentiel.
Exercice 3 Une séquence de n opérations est effectuée sur une structure de données. La i-ème
opération coûte i si i est une puissance de 2 et 1 sinon.
Le tableau a initialement une taille 1, on y met un élément et on fait grossir de 1
case.
Si on est en case i = 2k , on alloue i cases supplémentaires et on met 0 dedans. Ici
le potentiel est le nombre de cases occupées dans la seconde moitié du tableau.
1
1. Utiliser la méthode par agrégat pour calculer le coût amorti par opération.
2. Même question en utilisant la méthode du potentiel.
Chercher eventuellement un exemple de cout moyen facile a calculer puis faire un cout amorti
qu’on espere different.
Exercice 4 Soit k un entier positif. On considère les entiers naturels inférieur à 2 k . Étant
donné un tel entier x, son écriture en binaire peut être stockée dans un tableau A[0..k − 1] ne
contenant que des 0 et des 1 (le bit de poids le plus faible est stocké dans A[0]). On définit
l’opération Incrementer(A) comme suit :
Incrementer(A)
i <- 0 ;
tant que i < k et A[i] = 1 faire
A[i] <- 0
i <- i+1
fintantque
si i < k alors
A[i] <- 1
finsi
fin
1. Quel est l’effet de Incrementer ?
2. Le coût de l’opération Incrementer est le nombre de bits qui changent. On considère une
suite de n incrémentations à partir de 0 (on suppose n < 2 k ). Calculer le coût amorti de
l’opération Incrementer :
(a) en utilisant la méthode par agrégat
(b) en utilisant la méthode du potentiel.
3
Files de Fibonacci
Exercice 5 En désignant par Uk la famille des arbres binomiaux non ordonnés dont la racine
est de degré k (i.e. a k fils), on donne la définition inductive suivante des arbres binomiaux
non ordonnés :
U0 = {•}
Uk = {(•, Ui1 , . . . , Uik ) | (i1 , . . . , ik ) est une permutation de (0, . . . , k − 1) et U ij ∈ Uij }
Uk =
•
c
## c
c
#
c
#
c
#
U i1
...
U i2
U ik
Montrer que, pour tout arbre Uk de Uk :
1. Uk a 2k nœuds
2. La hauteur de Uk est k
3. Il y a Cki nœuds à la profondeur i (i = 0, . . . , k)
4. La racine de Uk est de degré k, supérieur au degré de n’importe quel autre nœud.
2
Exercice 6 Une file (ou tas) de Fibonacci est une collection d’arbres binomiaux non ordonnés
dont les étiquettes croissent des racines vers les feuilles. Une file de Fibonacci est dite consolidée
si toutes les racines ont des degrés différents.
1. Montrer que pour tout entier n, il existe une file de Fibonacci consolidée de taille n.
2. Quelles sont les tailles des arbres binomiaux non ordonnés qui forment une file de Fibonacci
de taille n ? les degrés des différentes racines ? le degré maximum d’un nœud ?
Exercice 7 Structure de données : Etant donnés une file de Fibonacci H et un nœud x
quelconque de H :
– min (H) désigne la racine de l’arbre qui contient la plus petite clé (si H est vide alors min (H) =
nil)
– pere (x) est le père de x (si x est une racine alors pere (x) = nil)
– fils (x) est l’un des fils de x (si x est une feuille alors fils (x) = nil)
– pred (x) est le frère gauche de x et succ (x) est son frère droit (si x est une racine alors pred (x)
et succ (x) sont des racines, si x est fils unique alors pred (x) = succ (x) = x)
– degre (x) est le nombre de fils de x.
Remarque : les racines sont reliées par une liste doublement chaı̂née ; les enfants d’un même
nœud sont eux aussi reliés par une liste doublement chaı̂née.
1. On dispose de la procédure CreerFibVide de création d’une file de Fibonacci vide. Écrire
les procédures
– InserererFib d’insertion d’un nœud x dans une file de Fibonacci (on insérera x dans
la liste des racines sans consolider la file)
– ConcatenerFib d’union de deux files de Fibonacci (sans consolidation).
2. Écrire une procédure ConsoliderFib de consolidation d’une file de Fibonacci.
3. Écrire une procédure d’extraction ExtraireMinFib du minimum dans une file de Fibonacci
(avec consolidation).
Exercice 8 En utilisant la méthode du potentiel, calculer le coût amorti de l’extraction du
minimum dans une file de Fibonacci.
Exercice 9 On rappelle que les nombres de Fibonacci sont définis par : F 0 = 0, F1 = 1 et
Fk+2 = Fk+1 + Fk pour k ≥ 0.
1. Calculer Fk .
2. Montrer que 1 +
k
X
Fi = Fk+2 .
i=0
√
5
1
+
(on a Φ ∼ 1, 61803).
3. Montrer que Fk+2 ≥ Φk avec Φ =
2
Exercice 10 Pour implémenter les opérations de diminution d’une clé et de suppression d’une
clé, on autorise tout nœud x d’une file de Fibonacci à avoir un fils de moins qu’il ne devrait,
avec un marquage de cette situation. Chaque nœud x contient un booléen marque (x) qui a la
valeur vrai s’il manque un fils à x et f aux sinon.
1. Écrire une procédure DiminuerCleFib de diminution d’une clé dans une file de Fibonacci.
2. Écrire une procédure SupprimerCleFib de suppression d’une clé dans une file de Fibonacci.
3. On note D(n) le degré maximum d’un nœud dans une file de Fibonacci de taille n. Montrer
que D(n) ≤ log Φ n.
4. En utilisant la méthode du potentiel, calculer le coût amorti de la suppression d’une clé
dans une file de Fibonacci.
3
4
Arbres bicolores et arbres 2-3-4
4.1
4.1.1
Arbres bicolores
Définition
Un arbre bicolore de recherche est un arbre binaire de recherche complété dans lequel tout sommet
possède une couleur (blanc ou rouge) et tout nœud interne possède une clé et qui vérifie :
• les feuilles sont blanches (et ne possèdent pas de clé)
• le père d’un sommet rouge est blanc
• les chemins issus d’un même sommet et se terminant en une feuille ont le même nombre
de sommets blancs.
4.1.2
Primitives
Pour manipuler les arbres bicolores, on dispose des primitives habituelles sur les arbres binaires :
ArbreVide :
− > arbre binaire
ArbreVide() renvoie un arbre vide
ArbreBinaire : élément × arbre binaire × arbre binaire − > arbre binaire
ArbreBinaire(x,G,D) renvoie l’arbre binaire dont la racine a pour contenu l’élément x
et dont les sous-arbres gauche et droit sont respectivement G et D
EstArbreVide : arbre binaire − > booléen
EstArbreVide(T) renvoie VRAI ssi T est un arbre binaire vide
Racine : arbre binaire − > élément
Racine(T) renvoie le contenu de la racine de l’arbre binaire T
SousArbreGauche : arbre binaire − > arbre binaire
SousArbreGauche(T) renvoie une copie du sous-arbre gauche de l’arbre binaire T
SousArbreDroit : arbre binaire − > arbre binaire
SousArbreDroit(T) renvoie une copie du sous-arbre droit de l’arbre binaire T
et de primitives spécifiques aux arbres bicolores :
FeuilleBlanche :
− > arbre binaire
FeuilleBlanche() renvoie l’arbre binaire réduit à une feuille de couleur c blanche
ArbreBinaire : clé × couleur × arbre binaire × arbre binaire − > arbre binaire
ArbreBinaire(a,c,G,D) renvoie l’arbre binaire dont la racine a pour clé a et
pour couleur c et dont les sous-arbres gauche et droit sont respectivement G et D
EstFeuille : arbre binaire − > booléen
EstFeuille(T) renvoie VRAI ssi T est un arbre binaire réduit à une feuille
CleRacine : arbre binaire − > clé
CleRacine(T) renvoie la clé de la racine de T
CouleurRacine : arbre binaire − > couleur
CouleurRacine(T) renvoie la couleur de la racine de T
ModifierCouleur : arbre binaire × couleur − > Rien
ModifierCouleur(T,c) remplace par c la couleur de la racine de l’arbre binaire T
4.2
Arbres 2-3-4
1. Rappeler les règles d’éclatement d’un 4-nœud dans un arbre 2-3-4, lorsque les éclatements
se font à la descente.
2. Construire par adjonctions successives un arbre 2-3-4 contenant les clés 8, 3, 2, 4, 1, 15,
10, 9, 11, 7, 6, 13, 12, 5, 14, 16, 17. On nommera cet arbre A-ex1.
4
4.3
4.3.1
Arbres 2-3-4 et arbres bicolores
Transformation d’un arbre 2-3-4 en arbre bicolore
Principe Pour obtenir un arbre bicolore à partir d’un arbre 2-3-4, on procède de la façon
suivante :
• l’arbre vide est transformé en une feuille blanche (sans clé)
• chaque 2-nœud prend la couleur blanche et ses deux sous-arbres sont transformés en arbres
bicolores
• un 3-nœud, qui compte deux clés a < b, se scinde en deux nœuds de l’arbre bicolore ; ces
deux nœuds contiennent respectivement les clés a et b. Il y a deux possibilités : ou bien b
est à la racine du sous-arbre droit de a ou bien a est à la racine du sous-arbre gauche de
b. Le fils prend la couleur rouge et le père prend la couleur blanche. Les trois sous-arbres
du 3-nœud sont eux-mêmes transformés en arbres bicolores et deviennent les sous-arbres
des nœuds contenant les clés a et b
• un 4-nœud, qui compte trois clés a < b < c, se scinde en trois nœuds de l’arbre bicolore ;
ces trois nœuds contiennent respectivement les clés a, b et c. La clé a est à la racine du
sous-arbre gauche de b et la clé c est à la racine du sous-arbre droit de b. Les fils prennent
la couleur rouge et le père prend la couleur blanche. Les quatre sous-arbres du 4-nœud
sont eux-mêmes transformés en arbres bicolores et deviennent les sous-arbres des nœuds
contenant les clés a et c.
1. Illustrer le principe énoncé ci-dessus (au moyen de petits dessins).
2. Montrer que l’arbre ainsi obtenu est un arbre bicolore et encadrer la hauteur de cet arbre.
3. Construire un arbre bicolore, que l’on nommera B-ex1, transformé de l’arbre 2-3-4 A-ex1.
4. Écrire l’algorithme de transformation d’un arbre 2-3-4 en arbre bicolore.
4.3.2
Transformation d’un arbre bicolore en arbre 2-3-4
1. Donner le principe de la transformation d’un arbre bicolore en arbre 2-3-4. Illustrer ce
principe au moyen d’un exemple.
2. Écrire l’algorithme de transformation d’un arbre bicolore en arbre 2-3-4.
4.4
4.4.1
Insertion dans un arbre bicolore
Rotations dans un arbre binaire
On définit les rotations simples RotationGauche et RotationDroite de spécifications :
RotationGauche : arbre binaire − > arbre binaire
RotationGauche(T) renvoie l’arbre obtenu en faisant basculer T vers la gauche
RotationDroite : arbre binaire − > arbre binaire
RotationDroite(T) renvoie l’arbre obtenu en faisant basculer T vers la droite
ainsi que les rotations doubles RotationDroiteGauche et RotationGaucheDroite de spécifications :
RotationDroiteGauche : arbre binaire − > arbre binaire
RotationDroiteGauche(T) renvoie l’arbre obtenu en faisant basculer d’abord le sous-arbre
droit de T vers la droite puis l’arbre T ainsi modifié vers la gauche
RotationGaucheDroite : arbre binaire − > arbre binaire
RotationGaucheDroite(T) renvoie l’arbre obtenu en faisant basculer d’abord le sous-arbre
gauche de T vers la gauche puis l’arbre T ainsi modifié vers la droite
1. Écrire la définition de l’une des deux rotations simples et la définition de l’une des deux
rotations doubles.
5
4.4.2
Insertion dans un arbre bicolore
Principe L’insertion dans un arbre bicolore suit le principe de l’insertion dans un arbre 2-3-4.
Nous travaillerons ici sur l’insertion avec éclatements à la descente.
1. Transposer dans les arbres bicolores les différents cas d’insertion d’une clé dans une feuille
d’un arbre 2-3-4.
2. Transposer dans les arbres bicolores les différents cas d’éclatement d’un 4-nœud.
3. Réaliser l’insertion des clés 13.1, 13.3, 12.5, 12.8 dans l’arbre bicolore B-ex1.
4. Écrire l’algorithme d’insertion d’une clé dans un arbre bicolore.
5. Ci-dessous figure un algorithme d’insertion extrait du livre “Introduction à l’algorithmique”
de Cormen, Leiserson, Rivest et Stein. Est-ce le même que le nôtre ?
Algorithmes d’insertion dans un ABR et dans un arbre bicolore
ARBRE-INSERER(T,z)
y <- NIL
x <- racine[T]
tant que x <> NIL
faire y <- x
si cle[z] < cle[x]
alors x <- gauche[x]
sinon x <- droit[x]
p[z] <- y
si y = NIL
alors racine[T] <- z
sinon si cle[z] < cle[y]
alors gauche[y] <- z
sinon droit[y] <- z
ROTATION-GAUCHE(T,x)
y <- droit[x]
droit[x] <- gauche[y]
si gauche[y] <> NIL
alors p[gauche[y]] <- x
p[y] <- p[x]
si p[x] = NIL
alors racine[T] <- y
sinon si x = gauche[p[x]]
alors gauche[p[x]] <- y
sinon droit[p[x]] <- y
gauche[y] <- x
p[x] <- y
Le code de ROTATION-DROITE est similaire au code de ROTATION-GAUCHE.
RN-INSERER(T,x)
ARBRE-INSERER(T,x)
couleur[x] <- ROUGE
tant que x <> racine[T] et couleur[p[x]] = ROUGE
faire si p[x] = gauche[p[p[x]]]
alors y <- droit[p[p[x]]]
si couleur[y] = ROUGE
alors couleur[p[x]] <- NOIR
couleur[y] <- NOIR
couleur[p[p[x]]] <- ROUGE
x <- [p[x]]
sinon si x = droit[p[x]]
alors x <- p[x]
ROTATION-GAUCHE(T,x)
couleur[p[x]] <- NOIR
couleur[p[p[x]]] <- ROUGE
ROTATION-DROITE(T,p[p[x]])
sinon (comme la clause alors
en echangeant droit et gauche)
couleur[racine[T]] <- NOIR
6
5
Hachage dynamique
5.1
Quelques exemples
Dans cette section, les éléments sont les lettres de l’alphabet : a, b, . . . y, z et leurs valeurs de
hachage sont h(a) = 00000, h(b) = 00001, . . . , h(y) = 11000, h(z) = 11001.
1. Réaliser le hachage dynamique des clés t, m, y, u, n, r, p, x, e, s, i, b, dans cet ordre, avec
pages de taille 4. Que se passe-t-il si on modifie l’ordre d’insertion des clés ?
2. Réaliser le hachage dynamique des clés a, b, c, d, e, f, g, h, i, j, k, l, dans cet ordre, avec pages
de taille 4, puis avec pages de taille 7.
5.2
Recherche et insertion
5.3
Primitives
Pour travailler sur le hachage dynamique, on utilisera les primitives suivantes (vous en compléterez
la spécification) :
IndexArbre : index × index − > index
IndexFeuille : page − > index
PageVide :
− > page
IndexGauche : index − > index
IndexDroit : index − > index
PageDeFeuille : index − > page
Element : page × entier − > élément
EstFeuille : index − > booléen
EstPagePleine : page − > booléen
EstDansPage : élément × page − > booléen
InsertionDansPage : page × élément − > page
On suppose que l’on dispose aussi d’une fonction :
BitHachage : élément × entier − > bit
BitHachage(x,k) renvoie le k-ième bit de la valeur de hachage de x
5.3.1
Recherche
Écrire un algorithme de recherche dans un index, avec pages de taille TaillePage.
5.3.2
Insertion
Écrire un algorithme d’insertion dans un index, avec pages de taille TaillePage.
7
Téléchargement