220 likes | 445 Views
TABLES D’ADRESSAGE DISPERSÉ (HASH TABLES; TABLES DE HACHAGE). OBJECTIFS. Comprendre le fonctionnement et l’implantation des tables d’adressage dispersé (hash tables). Être en mesure de pouvoir programmer des fonctions pour tables d’adressage dispersé.
E N D
OBJECTIFS • Comprendre le fonctionnement et l’implantation des tables d’adressage dispersé (hash tables). • Être en mesure de pouvoir programmer des fonctions pour tables d’adressage dispersé. • Être en mesure d’utiliser et d’implanter les dictionnaires et les ensembles avec des tables d’adressage dispersé. IFT1020
CODES • CBHT.java IFT1020
Tables d’adressage dispersé (Hash Tables) • Le BST possède des opérations en temps moyen dans O(log N), pour gérer N éléments dans une collection. • L’adressage dispersé est utilisé pour trouver rapidement des éléments d’une collection sans faire de recherche linéaire. En fait, on vise des opérations d’insertion, de suppression et de recherche dans O(1). • Une fonction d’adressage dispersé calcule une valeur entière (un index) pour tout objet dans la table. • Une bonne fonction d’adressage dispersé minimise les collisions, c’est-à-dire des index identiques pour des objets différents. • En java, pour calculer l’index (hash code) d’un objet x : int h = x.hashcode(); IFT1020
Une fonction d’adressage dispersé pour des mots… 26 lettres hashcode( mot ) = rang de la 1ère lettre A: 0 B: 1 … Z:25 Problème : plusieurs mots commencent par la même lettre impliquant une distribution non uniforme. IFT1020
Une fonction d’adressage dispersé pour des mots On pourrait aussi additionner la valeur ASCII des lettres du mot modulo M, où M est la taille de la table. C’est un meilleur choix car la distribution est meilleure (plus uniforme). IFT1020
Hash code classe de x x.hashcode( ) Date ms/232 xor ms % 232 ms depuis 01-01-1970 Integer valeur de x List Somme des hash code des éléments de la liste Set Somme des hash code des éléments du set String Somme des caractères de de la chaîne. IFT1020
Implantation simple Pour faire une implantation, il faut : • Une fonction de hashage pour les objets à traiter. • Une structure de données pour stocker les objets, par exemple un tableau. • Utiliser comme index du tableau des objets la valeur de hachage retournée par hashcode. Pour tester la présence d’un objet • Calculer son index à l’aide de hashcode. • Vérifier si la position à cet index dans le tableau est occupée. IFT1020
Exemple fictif IFT1020
Implantation dans un tableau IFT1020
Problèmes avec cette implantation • Il n’est pas possible de déclarer un tableau assez grand pour stocker des objets pour tous les index entiers. • Il est possible que deux objets différents aient le même index. IFT1020
Solutions • Prendre un tableau de taille « raisonnable » et réduire les index calculés dans l’intervale de ce tableau. int h = x.hashCode(); // hashcode système if(h < 0) h = -h; // élimine valeurs négatives h = h % taille; // ajuste pour entrer dans la table • Pour les objets qui ont le même index : • Utilisez des listes d’objets, qu’on appelle des “buckets”. IFT1020
Tableau de buckets • Une table d’adressage dispersé peut être implantée avec un tableau de buckets. • Les buckets sont des listes chaînées qui regroupent les éléments qui retournent le même index de hachage. • La taille de la table doit être un nombre premier plus grand que le nombre d’éléments attendu. • S’il y a peu de collisions (distribution uniforme des codes de hachage) alors les opérations ajouter, supprimer et chercher prennent un temps constant, dans O(1). IFT1020
Algorithme d’insertion • Obtenir l’index h dans la table : • Calculer le hashcode. • Réduire le hashcode modulo la taille de la table pour obtenir l’index h (si index peut déborder) • Ajouter dans le bucket à l’adresse h, revient à insérer dans une liste, O(n) : • Dépend de ce qu’on veut : liste triée, un ensemble, un BST,… ? IFT1020
Algorithme de recherche • Obtenir l’index h dans la table : • Calculer le hashcode. • Réduire le hashcode modulo la taille de la table pour obtenir l’index h (si index peut déborder) • Itérer dans le bucket à l’adresse h, revient à chercher dans une liste, O(n) : • Pour chaque élément dans le bucket vérifier s’il est égal à x. • Si on trouve un élément égal à x alors x est dans la liste et donc dans la table. • Autrement, x n’est pas dans la table. IFT1020
Algorithme de suppression • Obtenir l’index h dans la table : • Calculer le hashcode. • Réduire le hashcode modulo la taille de la table pour obtenir l’index h (si index peut déborder) • Itérer dans le bucket à l’adresse h, revient à supprimer dans une liste : • Pour chaque élément dans le bucket vérifier s’il est égal à x. • Si on trouve un élément égal à x alors on retire x de la liste et on le retourne. • Autrement, x n’est pas dans l’ensemble et on ne fait rien et on retourne null. IFT1020
Tableau périodique Nous allons faire un dictionnaire pour « mapper » les éléments chimiques avec leurs numéros atomiques. Nous prendrons comme fonction de hachage la première lettre de l’élément moins ‘A’. Nous implanterons la table dans un tableau avec « buckets ». IFT1020
<Rb, 37> <K, 19> <Ca, 20> <Li, 3> <He, 2> <Be, 4> <Cs, 55> <Ba, 56> <Sr, 38> <Mg, 12> <Na, 11> <H, 1> Tableau périodique 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Insérer <H, 1> : 7 Insérer <He, 2> : 7 Insérer <Li, 3> : 11 Insérer <Be, 4> : 1 Insérer <Na,11> : 13 Insérer <Mg,12> : 12 Insérer <K, 19> : 10 Insérer <Ca,20> : 2 Insérer <Rb,37> : 17 Insérer <Sr,38> : 18 Insérer <Cs,55> : 2 Insérer <Ba,56> : 1 … IFT1020
HashMap • Dans un HashMap, seules les clés sont hachées ! • Les clés ont besoin de hashCode et de méthodes equals compatibles (soit d’implanter l’interface Comparable). IFT1020
TreeSet vs HashSet • Les deux implantent l’interface Set • Avec une bonne fonction de hachage, les algorithmes qui travaillent avec une table de hachage sont généralement plus rapides que les algorithmes qui travaillent avec des arbres. • La classe TreeSet garantie le balancement des arbres et donc la performance dans O(log n) des opérations. • L’itérateur de TreeSet visite les éléments dans l’ordre trié alors que celui de HashSet non (plutôt un ordre aléatoire). IFT1020
Allons voir le code de CBHT.java… Ici on implante une table de hashing pour des entrées <clé, valeur>, donc prêt pour implanter HashMap. Pour implanter HashSet à partir de CBHT, il faudrait faire le même exercice qu’avec BSTSet, soit d’utiliser un objet bidon pour les valeurs. IFT1020