Vous êtes sur la page 1sur 88

Algorithmique :

structures de données
3 A I N FO, F I S E , S E M ESTR E 6
E N S I M, L E M A N S U N I V E RS ITÉ
2022 - 2023

LES TABLES DE HACHAGE


ENSEIGNANT : BACHAR EL HASSAN
ACCES AUX ÉLÉMENTS DU TDA LISTE

Pour trouver la position d’un élément e dans un TDA Liste de n éléments

• Comparaison de la valeur des éléments de la liste avec e


– Au pire : comparaison jusqu’au dernier élément
– Rercherche en O(n)

2
Recherche Dicothomique
O(Log 2 (n)

3
ACCÈS AUX ÉLÉMENTS – TABLE DE
HACHAGE
• Pour trouver la position d’un élément e dans une table de hachage de n éléments
• Calcul de la position de e dans la table
– accès direct à e
– un seul accès pour accéder à e
– recherche en O(1)
=> le calcul de la position d’un élément ne dépend pas du nombre d’éléments n

4
PRINCIPE DES TABLES DE HACHAGE

• La place d’un élément dans la table est calculée à partir de sa propre valeur

• Ce calcul est réalisé par une fonction de hachage : transforme la valeur de l’élément en
une adresse dans un tableau

5
FONCTION DE HACHAGE

Une table de hachage :


• utilisation d’une fonction de hachage
• l’indice d’un élément est donné par la fonction de hachage en fonction de la valeur de
l’élément
• pour une table T et un élément e, il existe une fonction de hachage
h telle que T[h(e)] = e (si e appartient à T)

6
EXEMPLE DE FONCTION DE HACHAGE

• E = ensemble des éléments à stocker


E = {serge, odile, luc, annie, anne, jean, julie, basile, paula, marcel, elise}
• N = taille de la table
N = 13
• Alors le rôle de la fonction de hachage h est le suivant :
associer à chaque élément e appartenant à E, une position h(e) comprise entre 0 et 12

7
Exemple d’algorithme de fonction h :
• Attribuer aux lettres a, b, ..., z les valeurs 1, 2, ... 26
• h(e) = (somme des valeurs des lettres de e + nombre des lettres de e ) modulo N
CALCUL DES POSITIONS DANS LA TABLE

• La position de l’élément serge sera donnée par h(serge)


• h(e) = (somme des valeurs des lettres de e + nombre des lettres de e ) modulo N
• h(serge) = ((19+5+18+7+5) + 5) modulo 13
= (54 + 5) modulo 13 = 7
• De même :
h(odile) = 11 h( julie) = 10
h(luc) = 0 h(basile) = 2
h(anne) = 12 h(paula) = 4
h(annie) = 9 h(elise) = 3
h( jean) = 8 h(marcel) = 6

9
• Comment trouver serge dans la table
?
• on calcule h(serge)
PROBLÈMES DES FONCTIONS DE HACHAGE

Reprenons l’exemple
• h(e) = (somme des valeurs des lettres de e + nombre des lettres de e ) modulo N

• Que se passe-t-il si l’ensemble E des prénoms à coder contient


– Axel et Alex ? h(axel) = h(alex) = 8
– Ilan et Lina ? h(ilan) = h(lina) = 10

• Collisions = plusieurs éléments à la même position

12
GESTION DES
COLLISIONS
COLLISIONS

• Une collision survient lorsque h(e1) = h(e2) mais e1 ≠ e2


• On montre qu’il est pratiquement impossible, même pour la meilleure des fonctions de
hachage d’éviter les collisions. Il est donc nécessaire de savoir les résoudre.
• 2 méthodes de résolution :
– résolution par chaînage : les éléments qui ont la même position sont chaînés entre eux, à
l’extérieur ou à l’intérieur de T. C’est le hachage indirect
– résolution par calcul : lorsqu’il y a collision, on calcule à partir de l’élément une nouvelle
place dans T. C’est le hachage direct

14
HACHAGE INDIRECT

• hachage indirect = les éléments en collision sont chaînés entre eux


• 2 types de gestion des collisions indirectes
– par hachage avec chaînage séparé
– par hachage coalescent

15
HACHAGE AVEC CHAINAGE SÉPARÉ

Tous les éléments en collision sont chaînés entre eux à l’extérieur de la table de hachage T
• les éléments de T sont alors des LISTES
• recherche, ajout, suppression d’un élément en collision : idem TDA LISTE
• La liste doit elle être triée ?
– Si la fonction de hachage est « bonne » alors il y aura peu de collision
• une recherche séquentielle dans une liste non triée suffit
– sinon :
• liste triée + algo de recherche adapté
• arbre binaire de recherche (équilibré)

16
HACHAGE COALESCENT

• Principe du hachage coalescent : tous les éléments en collisions sont chaînés entre eux, à
l’intérieur de la table de hachage T
– Pourquoi ?
Le chaînage séparé demande de l’allocation dynamique de la mémoire. Ce n’est pas toujours possible
– On réserve alors a priori tout l’espace mémoire nécessaire (positions “normales” + positions
collisions)
– La taille N de T est donc fixe
• Dans ce cas on divise T en 2 zones :
– Une zone d’adresses primaires de capacité p pour les positions “normales”
–Une zone d’adresses de réserve de capacité r pour les collisions
Les valeurs p et r sont fixées elles aussi à priori

30
SUPPRESSION AVEC CHAINAGE COALESCENT

Supprimer un élément dans T


• problème plus compliqué que l’ajout d’un élément
• Il faut décaler les éléments pour être à jour un chaînage dans T
plutôt que supprimer physiquement un élément, on préfère souvent marquer sa place comme
vide (pas de chaînage à modifier)

42
HACHAGE DIRECT

• Hachage direct = les éléments en collision sont mis à de nouvelles positions dans T.
Ces nouvelles positions sont gérées par calcul.
• 2 types de gestion des collisions directes
– par hachage linéaire
– par double hachage
• On définit une fonction d’essais successifs :
On cherche à placer e à une place p. Pour cela, on essaie dans l’ordre les cases p1(e), p2(e), ...
jusqu’à ce qu’on trouve une case libre

43
HACHAGE LINÉAIRE

S’il y a une collision à une position, on essaie la suivante


– p0(e) = h(e) : la première position testée est celle qui est donnée
– par la fonction de hachage
– p1(e) = (h(e) + 1) mod N
– ...
– pi(e) = (h(e) + i) mod N

avec i ∈ [0, N-1]

44
Algorithme d’ajout d’un élément
// première position testée : celle donnée par la fonction h
position ← h(e)
i ← 0
TANT QUE (i < N – 1) ET (position occupée) FAIRE
i← i+ 1
position ← (h(e) +i) mod N // on teste la position suivante
FINTANTQUE

45
HACHAGE LINÉAIRE

Algorithme de recherche d’un élément e dans T


position ← h(e)
i ← 0
TANT QUE (i < N – 1) ET (T[position] != e) ET (T[position ] != vide) FAIRE
i ← i + 1
position ← (h(e) + i) mod N

FINTANTQUE
SI T[position] == e ALORS trouvé
SINON pas trouvé

65
DOUBLE HACHAGE

• Si il y a une collision à la position i, on applique une seconde fonction de hachage h’(e)


• p0(e) = h(e) : la première position testée est celle qui est donnée par la fonction de hachage
• p1(e) = (h(e) + h’(e)) mod N
• p 2(e) = (h(e) + h’(e)*2) mod N
• ...
• pi(e) = (h(e) + h’(e) * i) mod N
avec i ∈ [0, N-1]
• Si h’(e) est une constante k, on observe des regroupements de k en k
– Si h’(e) = 1, on retrouve le hachage linéaire

66
h’(e) doit être premier avec N pour que T soit parcouru en totalité
• exemple 1 : N est une puissance de 2 et h’(e) toujours impaire
• exemple 2 : N premier, et h(e) positive et inférieure à N
– h(e) = e mod N
– h’(e) = 1 + (e mod N’) avec N’ légèrement inférieur à N

67
Algorithme d’ajout d’un élément
position ← h(e) // première position testée : celle donnée par la
fonction h
i ← 0
TANT QUE (i < N – 1) ET (position occupée) FAIRE
i← i + 1
position ← (h(e) + h’(e) *i) mod N // on teste la position suivante
FINTANTQUE

68
EXERCICE

• Soit les fonctions de hachage


– h1(e) = e mod N
– h2(e) = 1 + (e mod (N – 1))

• Insérer successivement les clés 10, 22, 31, 4, 15, 28, 17, 88 et 59 dans une table T de
hachage de taille N = 11 gérée en hachage linéaire : pi
(e) = (h1(e) + i) mod N
– Donner l’ensemble des positions pi pour chaque clé, et donner l’état final du tableau T.
– Même question avec T gérée en double hachage :
• pi(e) = (h1(e) + h2(e) * i) mod N

69
MÉTHODES DE
HACHAGE
RÔLE DE LA FONCTION DE HACHAGE

• transforme la valeur d’un élément en une position


• doit être déterministe
– pour retrouver les éléments c’est mieux
• doit être facilement calculable
– temps d’exécution de la fonction rapide, sinon on perd le bénéfice de l’accès en O(1)

71
CHOIX DE LA FONCTION

• Avoir une bonne « fonction » de hachage dépend de l’ensemble des éléments sur
lequel on travaille

• Exemple : si les éléments à coder sont des chaînes de caractères quelconques


– fonction qui utilise le code binaire des 2 premières lettres
– pas une bonne fonction si les chaînes à coder sont les noms de primitives du TDA Liste
(ListeCreer, ListeSupprimer ...)

72
EXEMPLES
Exemples de fonctions de hachage pour des mots (chaînes de caractères [A...Z] dont les lettres
sont codées sur 5 bits
A = 00001 F = 00110 K = 01011 P = 10000 U = 10101
B = 00010 G = 00111 L = 01100 Q = 10001 V = 10110
C = 00011 H = 01000 M = 01101 R = 10010 W = 10111
D = 00100 I = 01001 N = 01110 S = 10011 X = 11000
E = 00101 J = 01010 O = 01111 T = 10100 Y = 11001
Z = 11010
– Il s’agit des nombres de 1 à 26 codés en base 2
• Valeurs :
– mot "LES" = 01100 00101 10011
– mot "CAR" = 00011 00001 10010

• But de la fonction : h telle que


– h(mot) → indice dans [0..N-1] (N : taille de la table)

73
MÉTHODES DE HACHAGE

• Présentation de quelques principes de construction de fonctions de hachage qui


permettent :
– de dégager quelques techniques utiles
– d’éviter les pièges les plus courants
• Principales méthodes
– pour avoir une valeur de e
• Extraction
• Compression
– pour avoir un indice dans T
• Division
• Multiplication

74
MÉTHODES POUR TROUVER UNE
VALEUR DE E
• Le but est de transformer la valeur de l’élément en une valeur « représentable »
• Présentation de 2 méthodes
– par extraction
– par compression

75
MÉTHODE PAR EXTRACTION

• Principe
– on extrait une partie de la valeur (de la chaîne de bits) de l’élément e
• Par exemple
– seulement certains bits
– seulement certaines zones de bits

76
EXEMPLE

• extraction des bits 1, 2, 7 et 8 (en comptant de droite à gauche) de l’élément


• en les rapprochant, on obtient un entier entre 1 et 15

77
MÉTHODE PAR EXTRACTION

• Avantages
– calcul facile a mettre en oeuvre
• Inconvénients
– adaptée seulement a des cas particuliers
– quand on connaît la valeur des éléments a priori
– quand on sait que certains bits ne sont pas indicatifs
• En général, la méthode par extraction ne donne pas de bons résultats car elle ne
dépend pas de la totalité de la valeur de l’élément.
• Une bonne fonction de hachage utilise toute la valeur de e

78
MÉTHODE PAR COMPRESSION

• Principe
– On utilise tous les bits de e pour calculer son indice dans la table
• Exemple
– On découpe la chaîne de bits de l’élément en morceaux d’égale longueur
– On additionne les morceaux. Pour éviter les retenues on peut utiliser le « XOR » (ou exclusif) au lieu de l’addition
• On utilise xor qui renvoie des valeurs mieux réparties. Le ET ou le OU rendent systématiquement des nombres qui leur sont plus
petits (ET) ou plus grands (OU)
• Application : découpage en 5, la longueur du code d’une lettre
– ET = 00101 xor 10100 = 10001 → 17
– OU = 01111 xor 10101 = 11010 → 26
– NI = 01110 xor 01001 = 00111 → 7
– CAR = 00011 xor 00001 xor 10010 = 10000 → 16

79
PROBLÈME

• hache de la même façon toutes les permutations d’un même mot


h(CAR) = h(ARC)
• Vient du fait que toutes les sous chaines de bits sont des représentations de caractères
plusieurs sous-chaines peuvent être identiques

• Une "bonne" fonction de hachage doit briser les sous-chaînes de bits

80
AMÉLIORATIONS

On peut améliorer la fonction en faisant des décalages, par exemple circulairement vers la
droite, avec un pas différent pour chaque lettre.
• CAR = 00011 00001 10010
on décale de 1 le code de C, de 2 le code de A, de 3 le code de R
• ARC = 00001 10010 00011
on décale de 1 le code de A, de 2 le code de R, de 3 le code de C
• Dans ce cas
– CAR = 10001 xor 01000 xor 01010 = 10011 → 19
– ARC = 10000 xor 10100 xor 01100 = 01000 → 8
• Les anagrammes ont des codes différents

81
MÉTHODE POUR AVOIR UN INDICE
DANS T
• Le but est de ramener la représentation de e à un indice dans la table T de taille N
– indice [0, ..N- 1]
– indice [1, ..N]
• Présentation de deux méthodes
– par division
– par multiplication

82
MÉTHODE PAR DIVISION

• On calcule le reste de la division de la valeur de e par N


• Avantages :
fonctions de hachage facile et rapide à exécuter
• Inconvénients
Sa qualité dépend de la valeur de N.
• Exemple
– si N est pair alors tous les éléments vont aller dans les indices pairs de T
– si N est impair alors tous les éléments vont aller dans les indices impairs de T
– N ne doit par être une puissance de 2, car si N = 2p alors h(e) représente juste les p premiers bits
de e. Or il est préférable que h utilise tous les bits de la clé
– En général, on préfère prendre N premier

83
MÉTHODE PAR MULTIPLICATION

• Principe
basé sur la multiplication de e par un nombre réel θ (0 < θ < 1)
• Exemple :
– h(e) = [((e * θ) mod 1) * N] on garde la partie décimale du produit de e par θ , que l’on
multiplie par N (taille du tableau ou de la liste)

– Dans ce cas, la taille du tableau est sans importance, mais il faut éviter de prendre des
valeurs de θ trop proches de 0 ou de 1 pour éviter les accumulations aux extrémités du
tableau de hachage.

84
• Supposons que
– θ = 0.6125423371
– N = 30
• Alors h(ET)
= [((17 * θ ) mod 1) * N]
= [(10.4132197307 mod 1) * 30]
= [0. 4132197307 * 30]
= 12
• Avantage
– la taille du tableau est sans importance
• Inconvénients
– la valeur de θ doit être choisie avec soin
→ pas trop près de 0 ni de 1 pour éviter les accumulations aux extrémités de la table
– Des études théoriques montrent que les valeurs de θ qui repartissent uniformément les
éléments sont :
– θ = (√5 – 1 ) / 2 ~ 0.6180339887
– θ = 1 – (√5 – 1 ) / 2 ~ 0.3819660113
CONCLUSION SUR LES MÉTHODES DE
HACHAGE
pas de fonction de hachage universelle
– une "bonne" fonction doit être
• rapide a calculer
• repartir uniformément les éléments dans T
– mais cela dépend
• de la machine
• de l'application (contenu/valeur des éléments)

87
LIMITES DE LA FONCTION DE
HACHAGE
• But de la fonction h : attribuer 1 élément a chaque position de T
pas toujours possible.
• il peut y avoir des positions de T qui ne sont pas utilisées
– problème de "gaspillage mémoire"
– problème de taux de remplissage trop bas
• il y peut y avoir une place de T qui est attribuée à plusieurs éléments
problème des collisions

88

Vous aimerez peut-être aussi