📂 InsĂ©rer dans une Table de Hachage (22-hash-insert.c)


Introduction

L’insertion dans une table de hachage consiste à :

  1. Calculer l’indice oĂč la paire clĂ©-valeur sera stockĂ©e grĂące Ă  une fonction de hachage.
  2. GĂ©rer les collisions si plusieurs clĂ©s produisent le mĂȘme indice.
  3. Ajouter la paire clé-valeur dans la structure appropriée (par exemple, une liste chaßnée).

Plan d’ImplĂ©mentation

  1. CrĂ©er une structure pour reprĂ©senter un nƓud contenant la clĂ©, la valeur et un pointeur vers le prochain Ă©lĂ©ment (en cas de collision).
  2. ImplĂ©menter une fonction de hachage pour calculer l’indice Ă  partir de la clĂ©.
  3. Écrire la fonction insert pour :
    • Trouver l’indice.
    • InsĂ©rer la paire clĂ©-valeur dans la liste chaĂźnĂ©e du bucket correspondant.

Code Complet

Voici une implĂ©mentation dĂ©taillĂ©e en C de l’insertion dans une table de hachage :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
// Taille de la table de hachage
#define TABLE_SIZE 10
 
// Structure pour reprĂ©senter un nƓud dans un bucket
typedef struct Node {
    char *key;          // Clé
    int value;          // Valeur associée
    struct Node *next;  // Pointeur vers le prochain nƓud (gestion des collisions)
} Node;
 
// Table de hachage avec un tableau de pointeurs vers des buckets
Node *hash_table[TABLE_SIZE];
 
// Fonction de hachage : calcule un indice pour une clé donnée
unsigned int hash(const char *key) {
    unsigned int hash = 0;
    while (*key) {
        hash += *key++; // Somme des valeurs ASCII des caractĂšres
    }
    return hash % TABLE_SIZE; // Réduction au nombre de buckets
}
 
// Fonction pour insérer un élément dans la table de hachage
void insert(const char *key, int value) {
    unsigned int index = hash(key); // Calculer l'indice avec la fonction de hachage
 
    // CrĂ©er un nouveau nƓud
    Node *new_node = malloc(sizeof(Node));
    if (!new_node) {
        fprintf(stderr, "Erreur d'allocation mémoire\n");
        exit(EXIT_FAILURE);
    }
    new_node->key = strdup(key); // Copier la clé
    new_node->value = value;
    new_node->next = NULL;
 
    // Insérer dans le bucket (gestion des collisions par chaßnage)
    if (hash_table[index] == NULL) {
        // Pas de collision : le bucket est vide
        hash_table[index] = new_node;
    } else {
        // Collision : ajouter Ă  la tĂȘte de la liste chaĂźnĂ©e
        new_node->next = hash_table[index];
        hash_table[index] = new_node;
    }
}
 
// Fonction pour afficher la table de hachage (pour débogage)
void display() {
    for (int i = 0; i < TABLE_SIZE; i++) {
        printf("Bucket %d: ", i);
        Node *current = hash_table[i];
        while (current) {
            printf("[%s: %d] -> ", current->key, current->value);
            current = current->next;
        }
        printf("NULL\n");
    }
}
 
// Fonction principale pour tester l'insertion
int main() {
    // Initialiser la table de hachage
    for (int i = 0; i < TABLE_SIZE; i++) {
        hash_table[i] = NULL;
    }
 
    // Insérer des éléments
    insert("Alice", 25);
    insert("Bob", 30);
    insert("Charlie", 35);
    insert("Eve", 40);
    insert("Alice", 50); // Test avec une clé en collision
 
    // Afficher la table de hachage
    display();
 
    return 0;
}

Explication

1. Fonction de Hachage

  • La fonction hash calcule un indice Ă  partir de la clĂ© en :
    • Additionnant les valeurs ASCII des caractĂšres de la clĂ©.
    • RĂ©duisant cette somme au nombre total de buckets (TABLE_SIZE) Ă  l’aide de l’opĂ©rateur %.

2. Insertion

  • Cas sans collision : Si le bucket est vide (NULL), on insĂšre directement le nƓud.
  • Cas avec collision : Si le bucket contient dĂ©jĂ  des Ă©lĂ©ments, on insĂšre le nouveau nƓud en tĂȘte de la liste chaĂźnĂ©e.

3. Gestion des Collisions

Les collisions sont gĂ©rĂ©es Ă  l’aide de listes chaĂźnĂ©es :

  • Si plusieurs clĂ©s produisent le mĂȘme indice, elles sont ajoutĂ©es dans une liste chaĂźnĂ©e au mĂȘme bucket.

4. Affichage

La fonction display parcourt chaque bucket et affiche les Ă©lĂ©ments qu’il contient (utile pour vĂ©rifier l’état de la table).


Exemple d’ExĂ©cution

Entrées

  • insert("Alice", 25)
  • insert("Bob", 30)
  • insert("Charlie", 35)
  • insert("Eve", 40)
  • insert("Alice", 50) (collision volontaire)

Sortie

Bucket 0: NULL
Bucket 1: [Eve: 40] -> NULL
Bucket 2: NULL
Bucket 3: [Alice: 50] -> [Alice: 25] -> NULL
Bucket 4: [Charlie: 35] -> NULL
Bucket 5: NULL
Bucket 6: NULL
Bucket 7: NULL
Bucket 8: [Bob: 30] -> NULL
Bucket 9: NULL

Améliorations Futures

  1. DĂ©tection des ClĂ©s Duplicates : VĂ©rifier si la clĂ© existe dĂ©jĂ  avant d’insĂ©rer.
  2. Gestion Dynamique : Redimensionner la table si elle devient trop pleine.
  3. Suppression : Ajouter une fonction pour supprimer une clĂ© et son nƓud.

Résumé

  1. Insertion dans une table de hachage implique :
    • Calculer l’indice avec une fonction de hachage.
    • GĂ©rer les collisions en utilisant des listes chaĂźnĂ©es.
    • Ajouter la paire clĂ©-valeur au bon endroit.
  2. Les collisions sont gĂ©rĂ©es en chaĂźnant les nƓuds dans le mĂȘme bucket.

Si quelque chose n’est pas clair, je peux dĂ©tailler encore plus ou simplifier davantage ! 😊