Les tables de hachage sont des structures de données puissantes permettant un accès rapide aux données grâce à des fonctions de hachage. Elles sont essentielles pour des opérations efficaces d'insertion, de recherche et de suppression.
Une table de hachage est une structure de données qui stocke des paires clé-valeur. Elle utilise une fonction de hachage pour convertir une clé en un index dans un tableau, permettant un accès quasi constant aux données.
Une fonction de hachage efficace doit respecter les propriétés suivantes :
Les collisions se produisent lorsque deux clés différentes produisent le même index. Il existe deux méthodes principales pour les résoudre :
Chaque emplacement de la table pointe vers une liste qui stocke toutes les paires clé-valeur ayant le même index.
Au lieu d'utiliser des listes, on cherche une autre case libre dans la table pour insérer la nouvelle paire. Les techniques incluent le sondage linéaire, quadratique et le double hachage.
class HashTableSeparateChaining:
def __init__(self, taille=10):
self.table = [[] for _ in range(taille)]
def _hash_function(self, cle):
return hash(cle) % len(self.table)
def inserer(self, cle, valeur):
index = self._hash_function(cle)
for i, (k, v) in enumerate(self.table[index]):
if k == cle:
self.table[index][i] = (cle, valeur)
return
self.table[index].append((cle, valeur))
def rechercher(self, cle):
index = self._hash_function(cle)
for k, v in self.table[index]:
if k == cle:
return v
return None
def supprimer(self, cle):
index = self._hash_function(cle)
for i, (k, v) in enumerate(self.table[index]):
if k == cle:
del self.table[index][i]
return True
return False
Explication du Code : Cette implémentation utilise une liste de listes pour gérer les collisions. Chaque index de la table contient une liste de paires clé-valeur.
class HashTableLinearProbing:
def __init__(self, taille=10):
self.table = [None] * taille
def _hash_function(self, cle):
return hash(cle) % len(self.table)
def inserer(self, cle, valeur):
index = self._hash_function(cle)
while self.table[index] is not None:
if self.table[index][0] == cle:
self.table[index] = (cle, valeur)
return
index = (index + 1) % len(self.table)
self.table[index] = (cle, valeur)
def rechercher(self, cle):
index = self._hash_function(cle)
while self.table[index] is not None:
if self.table[index][0] == cle:
return self.table[index][1]
index = (index + 1) % len(self.table)
return None
def supprimer(self, cle):
index = self._hash_function(cle)
while self.table[index] is not None:
if self.table[index][0] == cle:
self.table[index] = None
return True
index = (index + 1) % len(self.table)
return False
Explication du Code : Cette implémentation utilise un tableau où, en cas de collision, on cherche séquentiellement le prochain emplacement libre.
Pour une table de hachage bien équilibrée :
Opération | Complexité Moyenne | Complexité Pire Cas |
---|---|---|
Insertion | O(1) | O(n) |
Recherche | O(1) | O(n) |
Suppression | O(1) | O(n) |
Testez vos connaissances avec ces exercices :
# Exercices :
# 1. Implémentez une table de hachage en utilisant le sondage quadratique pour l'adressage ouvert.
# 2. Écrivez une fonction pour redimensionner automatiquement la table de hachage lorsque le taux de remplissage dépasse un certain seuil.
# 3. Créez une fonction de hachage personnalisée pour une table de hachage qui stocke des objets complexes.
# 4. Implémentez une méthode pour gérer les collisions en utilisant le double hachage.
# 5. Écrivez un programme pour analyser les performances de différentes méthodes de résolution des collisions.
Les tables de hachage sont des structures de données essentielles pour des opérations de recherche, d'insertion et de suppression rapides. Comprendre les différentes méthodes de gestion des collisions vous permettra de choisir la meilleure approche pour vos applications.