Corrigé 3. Enoncé
1. Hachage ou rangement dispersé dans une table
Structures de données utilisées
Chaque entrée de la table est composée de deux champs :
- Nb : nombre courant d'éléments
- Tab : les articles
TYPE Typebloc = STRUCTURE
Nb : ENTIER
Tab : TABLEAU[1..B] DE
Typecle
FIN
Donc, la table est définie comme suit :
VAR Table : TABLEAU[0..M-1]
DE Typebloc
Typecle peut être tout ensemble muni d'une relation d'ordre.
Module de recherche
H := Hash(Cle) { Hash désigne la fonction de hachage }
Continue := VRAI
TANTQUE Continue :
{ Rechercher dans l'entrée H de Table }
Trouv := FAUX ; I := 1
TANTQUE NON Trouv ET I <= Table(H).Nb
SI Table(H).Tab(I) =
Cle :
Trouv := VRAI
SINON
I := I + 1
FSI
FINTANTQUE
SI Trouv :
Continue := FAUX
SINON
SI Table(H).Nb < B :
Continue := FAUX
SINON
H := H - 1; SI H < 0 : H:=H+M FSI
FSI
FSI
FINTANTQUE
Module d'insertion
Soient Trouv et H les paramètres donnés par le module de Recherche.
N étant une variable globale contenant à tout moment le nombre d'éléments rangés dans
Table.
SI Trouv :
"Insertion impossible"
SINON
N := N + 1
SI N = M*B - 1 :
"Débordement"
SINON
Table(H).Nb :=
Table(H).Nb + 1
Table(H).Tab(Table(H).Nb) := Cle
FSI
FSI
Remarquer que la table est considérée comme pleine quand il reste une seule clé à
ranger.
Module de suppression
Soit Trouv, H et I les paramètres donnés par le module Recherche. I est donc l'indice de
l'élément à supprimer dans la case H de la table.
SI Trouv :
N := N - 1 { Nombre d'éléments dans la table
}
Continue := VRAI
TANTQUE Continue :
{Supprimer le i-ième
élément de l'entrée H de Table}
SI I # Table(H).Nb : {
Déplacer l'article }
Table(H).Tab(I) := Table(H).Tab(Table(H).Nb)
FSI
Table(H).Nb :=
Table(H).Nb - 1
Place := ( Table(H).Nb
# B-1)
Cond := FAUX
J := H
TANTQUE NON Place ET
NON Cond:
{L'entrée H était pleine}
H:=H-1;SI H<0 : H:=H+M FSI
K := 1
TANTQUE K <= Table(H).Nb ET NON Cond :
R := Hash( Table(H).Tab(K) )
SI J > H :
Test := R<H OU R >= J
SINON Test := R < H ET R >= J FSI
SI Test : Cond := VRAI
SINON K := K + 1 FSI
FINTANTQUE
SI NON Cond ET Table(H).Nb < B :
Place := VRAI
FSI
FINTANTQUE
SI Place : Continue :=
FAUX
SINON
Table(J).Tab(B) := Table(H).Tab(K)
I := K
FSI
FINTANTQUE
SINON " Clé inexistante " FSI
2. Fichiers structurés en tableaux
Description de F :
TYPE Typebloc = STRUCTURE
T : Tableau[1..B] DE
Typecle
Nb : ENTIER { Nombre
d'articles}
FIN
Typecle peut être tout ensemble muni d'une relation d'ordre.
Module de recherche dichotomique :
Soit Buffer une zone mémoire de type Typebloc.
{ Recherche dichotomique externe }
Trouv := FAUX
Bi := 1
Bs := M { Dernier bloc }
TANTQUE Bi <= Bs ET NON Trouv :
Milieu := (Bi+Bs) DIV 2 { Division entière }
Lirebloc(F, Milieu, Buffer)
SI Buffer.T(1) <= Cle ET
Buffer.T(Buffer.Nb) >= Cle :
Trouv := VRAI
SINON
SI Cle <
Buffer.T(1):
Bs := Milieu - 1
SINON
Bi := Milieu + 1
FSI
FSI
FINTANTQUE
{ Recherche dichotomique interne }
SI Trouv :
Trouv := FAUX
Binf := 1
Bsup := Buffer.Nb { Nombre d'éléments }
TANTQUE Binf <= Bsup ET NON Trouv :
Mil := (Binf+Bsup) DIV
2
SI Buffer.T(Mil) = Cle
Trouv := VRAI
SINON
SI Cle < Buffer.T(Mil)
Bsup := Mil - 1
SINON
Binf := Mil + 1
FSI
FSI
FINTANTQUE
SINON
SI Bs = M
Binf := Buffer.Nb + 1
SINON
Binf := 1
FSI
FSI
Remarque : si Trouv est FAUX, Milieu pointe le bloc qui devait contenir la clé
recherchée et Binf la position o� elle devrait se trouver dans ce bloc.
Module d'insertion :
Soit Trouv, Milieu et Binf les paramètres donnés par le module de Recherche dans le cas
o� la clé à inserer n'existe pas.
SI NON Trouv :
SI Buffer.Nb = B:
{Rechercher un bloc
libre dans les blocs I+1,
I-1,I+2, I-2, . . . }
Inf, Sup := Milieu
Creerpile(Linf);Empiler(Linf, Buffer.T(1))
Creerpile(Lsup);Empiler(Lsup, Buffer.T(B) )
Aig, Trouv := FAUX
S := 0
TANTQUE NON Trouv ET S
< 2 :
SI Aig :
Inf := Inf - 1
K := Inf
SINON
Sup := Sup + 1
K := Sup
FSI
SI 1 <= K <= M
Lirebloc(F, K, Buffer)
SI Buffer.Nb < B :
Trouv := VRAI
SINON
SI Aig :
Empiler(Linf,Buffer.T(1))
SINON
Empiler(Lsup,Buffer.T(B))
FSI
Aig := NON Aig
FSI
SINON
S := S + 1
FSI
FINTANTQUE
{ Décalage }
SI NON Trouv :
M := M + 1 { Extension du fichier }
K := M
Buffer.Nb := 0
FSI
SI K > Milieu :
{Décalage dans le bloc K }
POUR J=Buffer.Nb,1, -1 :
Buffer.T(J+1) :=Buffer.T(J)
FINPOUR
Depiler(Lsup,Elmt)
Buffer.T(1) := Elmt
Buffer.NB := Buffer.Nb + 1
Ecrirebloc(F, K, Buffer)
POUR I=K-1, Milieu, -1 :
Lirebloc(F,I,Buffer)
SI I = Milieu :
Limit := Binf
SINON
Limit := 1
FSI
POUR J=Buffer.Nb - 1 , Limit, -1 :
Buffer.T(J+1) :=Buffer.T(J)
FINPOUR
SI I = Milieu :
Buffer.T(Binf) := Cle
SINON
Depiler(Lsup, Elmt)
Buffer.T(1) := Elmt
FSI
Ecrirebloc(F, I, Buffer)
FINPOUR
SINON
Depiler(Linf, Elmt)
Buffer.NB := Buffer.Nb + 1
Buffer.T(Buffer.Nb) := Elmt
Ecrirebloc(F, K, Buffer)
POUR I=K+1, Milieu :
Lirebloc(F,I,Buffer)
SI I = Milieu :
Limit := Binf - 2
SINON
Limit := Buffer.Nb - 1
FSI
POUR J=1, Limit:
Buffer.T(J):=Buffer.T(J+1)
FINPOUR
SI I = Milieu :
Buffer.T(Binf) := Cle
SINON
Depiler(Linf, Elmt)
Buffer.T(B) := Elmt
FSI
Ecrirebloc(F, I, Buffer)
FINPOUR
FSI
SINON { Buffer.Nb < B }
{Insertion de Cle dans
le bloc Milieu à la position Binf}
POUR J=Buffer.Nb,Binf,
1, -1
Buffer.T(J+1) := Buffer.T(J)
FINPOUR
Buffer.T(Binf) := Cle
Buffer.Nb := Buffer.Nb
+ 1
Ecrirebloc(F, Milieu,
Buffer)
FSI
SINON
" Clé existe "
FSI
Description de F
TYPE Typebloc = STRUCTURE
T : TABLEAU[1..B] DE
Typecle
Nb : ENTIER { Nombre
d'articles}
Lien : Typeadresse
FIN
TYPE Typeadresse = STRUCTURE
Numbloc : ENTIER
Tetelist : ENTIER
FIN
Description de F'
TYPE Typebloc' = STRUCTURE
T' : TABLEAU[1..M] DE
Typemaillon
Lien' : ENTIER
FIN
TYPE Typemaillon= STRUCTURE
Cle : Typecle
Suiv : Typeadresse
FIN
Pour pouvoir pratiquer toujours la recherche dichotomique sur le fichier F, nous convenons
de faire les suppositions suivantes :
- Buffer.T(B) est toujours supérieur à tous les éléments de la liste se trouvant sur
le fichier F'.
- les listes sont ordonnées.
- la liste de débordements n'existe que si le bloc primaire est rempli. Donc, quand on
effectue une suppression d'un article d'un bloc rempli du fichier F, on doit ramener un
élément de la liste de débordements si celle-ci existe.
Nous utilisons les modules suivants :
Rechdicho(F, Cle, Trouv, I) : recherche dichotomique d'une clé Cle sur le fichier F. Si
la clé est trouvée, Trouv est VRAI et I pointe le bloc contenant cette clé.
Rechlist (Buffer.Lien, Cle, Trouv, K) : recherche d'une clé Cle dans une liste linéaire
chaînée de tête Buffer.Lien contenue dans F'. Si la clé est trouvée, Trouv est VRAI
et K pointe l'entrée dans le bloc contenant cette clé.
Module de recherche/insertion
Rechdicho(F, Cle, Trouv, I)
SI NON Trouv : { Le bloc I est dans Buffer }
SI Buffer.Nb < B :
. Inserer la clé Cle
dans ce buffer
SINON
SI Buffer.Lien.Numbloc
= NIL :
. Créer une liste avec la clé Cle
SINON
Rechlist(Buffer.Lien, Cle, Trouv",K)
SI NON Trouv" :
. Inserer la cle Cle dans la liste
FSI
FSI
FSI
FSI
Recherche dans le fichier de débordements
On a, en entrée :
Num : le numéro du bloc o� commence la liste.
L : la tête de liste dans ce bloc.
Clé : clé à rechercher.
et en sortie :
Trouv : vrai si la clé est trouvée, faux sinon.
K : position de la clé dans le cas o� la clé est trouvée.
Trouv := FAUX
Lirebloc(F', Num, Buffer)
TANTQUE L # -1 ET NON Trouv :
SI Buffer.T'(L).Article.Cle= Cle :
Trouv := VRAI
SINON
L :=
Buffer.T(L).Suiv.Tetelist
SI
Buffer.T(L).Suiv.Numbloc # Num :
Num := Buffer.T(L).Suiv.Numbloc
Lirebloc(F, Num, Buffer)
FSI
FSI
FINTANTQUE