NSI · Bac Terminale

Dictionnaires et tables de hachage

Cours complet, fiche de révision, QCM corrigés et exercices types sur Dictionnaires et tables de hachage en NSI. Programme officiel BO 2024, validé par des profs certifiés.

Cours complet
BO 2024
Fiche révision
Synthèse 1 page
QCM corrigé
Auto-évaluation
Prof IA
24h/24

Cours complet : Dictionnaires et tables de hachage

Les dictionnaires sont des structures de donnees associatives qui permettent de stocker des paires clé-valeur et d'acceder rapidement a une valeur a partir de sa clé. Ils reposent en interne sur le mecanisme de hachage, qui transforme une clé en indice de tableau.

Une table de hachage utilise une fonction de hachage pour transformer une clé en indice dans un tableau. Ce mecanisme permet un acces en O(1) en moyenne, ce qui en fait une structure extremement efficace pour la recherche, l'insertion et la suppression.

Les collisions, situation ou deux clés produisent le meme indice, sont inevitables et doivent etre gerees par des strategies specifiques : le chainage externe (listes chainees a chaque case) ou l'adressage ouvert (recherche d'une case libre).

Comprendre le fonctionnement interne des dictionnaires, la notion de collision, les strategies de résolution et le facteur de charge est fondamental en informatique. Le type dict de Python, omnipresent dans le langage, est implemente comme une table de hachage optimisee.

Prérequis

  • Notion de tableau et d'indice
  • Listes chainees (pour le chainage externe)
  • Notion de complexite algorithmique O(1), O(n)
  • Objets immuables vs mutables en Python

1. Principe du hachage

Le hachage consiste a transformer une donnee de taille quelconque en un entier de taille fixe grace a une fonction de hachage. Cet entier sert d'indice dans un tableau pour stocker ou retrouver la valeur associée a la clé. L'idee fondamentale est de calculer directement la position de stockage plutot que de chercher sequentiellement.

Une bonne fonction de hachage doit etre deterministe (meme entree produit toujours la meme sortie), rapide a calculer, et distribuer uniformement les clés dans le tableau pour minimiser les collisions. Une mauvaise distribution concentre les clés dans quelques cases et degrade les performances.

En Python, la fonction hash() retourne le hash d'un objet. Seuls les objets immuables (int, str, tuple d'immuables) sont hachables. Les listes et dictionnaires, etant mutables, ne peuvent pas servir de clés car leur hash pourrait changer apres modification, rendant la clé introuvable dans la table.

L'indice dans le tableau est généralement obtenu par hash(clé) % taille_tableau. La taille du tableau est choisie pour equilibrer la consommation memoire et le taux de collisions. Plus le tableau est grand, moins il y a de collisions, mais plus la memoire est gaspillee.

Méthode — Implementer une table de hachage simple

  1. Creer un tableau de taille fixe (par ex. 10 cases), chaque case etant une liste vide
  2. Pour inserer (clé, valeur) : calculer indice = hash(clé) % taille
  3. Ajouter la paire (clé, valeur) dans la liste a l'indice calcule
  4. Pour rechercher : calculer l'indice puis parcourir la liste a cet indice
  5. Pour supprimer : trouver et retirer la paire de la liste

Exemple : On dispose d'une table de hachage de taille 7. Inserer les clés suivantes avec h(clé) % 7 : h('alice')=3, h('bob')=5, h('charlie')=3, h('diana')=1. Montrer l'état de la table avec chainage externe.

  1. Insertion de 'alice' : h('alice') % 7 = 3. Table[3] = [('alice', val)]
  2. Insertion de 'bob' : h('bob') % 7 = 5. Table[5] = [('bob', val)]
  3. Insertion de 'charlie' (collision) : h('charlie') % 7 = 3. Collision avec 'alice'. Table[3] = [('alice', val), ('charlie', val)]
  4. Insertion de 'diana' : h('diana') % 7 = 1. Table[1] = [('diana', val)]
  5. état final : Table[0]=[], Table[1]=[('diana',val)], Table[2]=[], Table[3]=[('alice',val),('charlie',val)], Table[4]=[], Table[5]=[('bob',val)], Table[6]=[]

⚠️ Attention : En Python, les listes et dictionnaires sont mutables et donc NON hachables. On ne peut pas les utiliser comme clés de dictionnaire. Utiliser des tuples (immuables) a la place.

2. Gestion des collisions

Une collision survient quand deux clés differentes produisent le meme indice apres hachage. C'est inevitable quand le nombre de clés possibles depasse la taille du tableau (principe des tiroirs de Dirichlet).

Le chainage externe resout les collisions en stockant a chaque case du tableau une liste chainee contenant toutes les paires (clé, valeur) ayant le meme indice. La recherche parcourt la liste a l'indice correspondant. En moyenne, si les éléments sont bien distribues, chaque liste a une longueur de n/taille, d'ou un acces moyen en O(1 + n/taille).

L'adressage ouvert resout les collisions en cherchant une autre case libre dans le tableau selon une sequence de sondage. Le sondage linéaire teste les cases consecutives (i+1, i+2, ...). Le sondage quadratique teste i+1, i+4, i+9, ... Le double hachage utilise une seconde fonction pour calculer le pas de sondage.

Le facteur de charge (nombre d'éléments / taille du tableau) mesure le remplissage. Quand il depasse un seuil (souvent 0.75 en Python), le tableau est redimensionne (généralement double) et tous les éléments sont re-haches dans le nouveau tableau plus grand pour maintenir les performances. Cette opération de rehachage est en O(n) mais est suffisamment rare pour etre amortie.

Méthode — résoudre une collision par chainage externe

  1. Calculer l'indice : i = hash(clé) % taille
  2. Acceder a la liste chainee a table[i]
  3. Parcourir la liste pour vérifier si la clé existe deja
  4. Si oui : mettre a jour la valeur
  5. Si non : ajouter la paire (clé, valeur) en fin de liste

Exemple : Dans une table de taille 5 avec adressage ouvert (sondage linéaire), inserer les clés dont les hash modulo 5 sont : A->2, B->2, C->2, D->4. Montrer l'état de la table.

  1. Insertion de A : h(A) = 2. Table[2] est vide. Table[2] = A
  2. Insertion de B (collision) : h(B) = 2. Table[2] est occupee par A. Sondage linéaire : Table[3] est vide. Table[3] = B
  3. Insertion de C (collision) : h(C) = 2. Table[2] occupee, Table[3] occupee. Table[4] est vide. Table[4] = C
  4. Insertion de D (collision) : h(D) = 4. Table[4] est occupee par C. Table[0] est vide (sondage circulaire). Table[0] = D

⚠️ Attention : O(1) est la complexite MOYENNE, pas le pire cas. Si toutes les clés collisionnent (meme indice), la complexite degene en O(n). C'est pourquoi la fonction de hachage et le facteur de charge sont cruciaux.

3. Les dictionnaires Python

Le type dict de Python est implemente comme une table de hachage hautement optimisee. L'acces, l'insertion et la suppression sont en O(1) en moyenne. Dans le pire cas (toutes les clés collisionnent), ces opérations sont en O(n), mais cela est extremement rare avec une bonne fonction de hachage.

Les opérations principales sont : d[clé] = valeur (insertion ou modification), d[clé] (acces, leve KeyError si absent), del d[clé] (suppression), clé in d (test d'appartenance en O(1) moyen), d.keys() (les clés), d.values() (les valeurs), d.items() (les paires clé-valeur).

Les dictionnaires Python maintiennent l'ordre d'insertion depuis Python 3.7 (garanti par la specification). Attention : cet ordre n'est pas un tri, c'est simplement l'ordre dans lequel les clés ont ete ajoutees. Pour un parcours trie, il faut utiliser sorted(d).

La méthode get(clé, defaut) evite les KeyError en fournissant une valeur par defaut si la clé n'existe pas. Les comprehensions de dictionnaires {k: v for k, v in ...} permettent de creer des dictionnaires de maniere concise et sont tres utilisees en Python idiomatique.

Méthode — Compter les occurrences avec un dictionnaire

  1. Creer un dictionnaire vide : compteur = {}
  2. Parcourir chaque élément de la sequence
  3. Pour chaque élément, utiliser get pour obtenir le comptage actuel (0 par defaut)
  4. Incrementer : compteur[elem] = compteur.get(elem, 0) + 1
  5. Le dictionnaire contient les occurrences de chaque élément

Exemple : écrire une fonction qui prend une chaine de caracteres et retourne un dictionnaire contenant le nombre d'occurrences de chaque lettre. Appliquer a 'abracadabra'.

  1. Initialisation : compteur = {}
  2. Parcours et comptage : Pour chaque lettre de 'abracadabra' : compteur['a'] = 0+1 = 1, puis 2, 3, 4, 5 compteur['b'] = 0+1 = 1, puis 2 compteur['r'] = 0+1 = 1, puis 2 compteur['c'] = 0+1 = 1 compteur['d'] = 0+1 = 1
  3. Code : def compter_lettres(texte): compteur = {} for lettre in texte: compteur[lettre] = compteur.get(lettre, 0) + 1 return compteur
  4. résultat : compter_lettres('abracadabra')

⚠️ Attention : Le dictionnaire Python conserve l'ordre d'insertion (depuis 3.7) mais ce n'est PAS un tri. Ne pas confondre ordre d'insertion et ordre alphabetique/numerique.

4. Complexite et limites

La complexite en moyenne d'une table de hachage est O(1) pour la recherche, l'insertion et la suppression. C'est son avantage majeur par rapport aux tableaux tries (O(log n) en recherche par dichotomie) et aux listes chainees non triees (O(n) en recherche).

Dans le pire cas, si toutes les clés collisionnent (par exemple si la fonction de hachage est mauvaise), la complexite degene en O(n) car on se retrouve essentiellement avec une seule liste chainee. C'est pourquoi le choix de la fonction de hachage et la gestion du facteur de charge sont cruciaux.

Les tables de hachage ne permettent pas un parcours ordonne des clés (sauf si elles sont triees separement). Pour des opérations necessitant un ordre (minimum, maximum, parcours croissant), un arbre binaire de recherche equilibre est preferable car il offre O(log n) pour toutes les opérations tout en maintenant l'ordre.

La consommation memoire d'une table de hachage est supérieure a celle d'un simple tableau car le tableau sous-jacent doit etre surdimensionne pour maintenir un facteur de charge faible et minimiser les collisions. C'est le compromis classique temps-memoire en informatique.

Méthode — Choisir entre table de hachage et arbre de recherche

  1. Si besoin d'acces en O(1) sans ordre : table de hachage (dict)
  2. Si besoin de parcours ordonne (min, max, tri) : arbre de recherche
  3. Si les clés sont immuables : dict possible
  4. Si les clés sont mutables : impossible avec dict, utiliser une autre structure
  5. Si la memoire est critique : un tableau trie peut etre plus economique

Exemple : Comparer les complexites de recherche d'un élément dans : (a) un tableau non trie, (b) un tableau trie, (c) une table de hachage. Conclure sur le choix de structure.

  1. Tableau non trie : Recherche linéaire : parcourir élément par élément.
  2. Tableau trie : Recherche dichotomique : diviser l'espace de recherche par 2 a chaque étape.
  3. Table de hachage : Calcul de l'indice par hash puis acces direct (en moyenne).
  4. Comparaison numerique : Pour n = 1 000 000 éléments : Tableau non trie : ~1 000 000 comparaisons Tableau trie : ~20 comparaisons (log2(10^6) ≈ 20) Table de hachage : ~1 acces

⚠️ Attention : Ne pas confondre hash (hachage pour stockage en O(1)) et chiffrement (securite). La fonction hash() de Python n'est PAS une fonction cryptographique.

Conclusion

Les dictionnaires et tables de hachage offrent un acces en O(1) en moyenne grace au mecanisme de hachage. La gestion des collisions (chainage externe ou adressage ouvert) et le facteur de charge sont essentiels pour maintenir les performances. En Python, le type dict est omnipresent et constitue un outil fondamental. L'essentiel au BAC est de comprendre le fonctionnement interne, les complexites moyennes et pire cas, et les contraintes sur les clés (immuabilite).

Mots-clés

dictionnairetable de hachagefonction de hachagecollisionchainagefacteur de chargeclé-valeurhashO(1)immuable

Fiche de révision : Dictionnaires et tables de hachage

Notions clés

Table de hachage
Structure associative utilisant une fonction de hachage pour stocker des paires clé-valeur avec acces en O(1) moyen.
Exemple : Le type dict de Python.
Fonction de hachage
Fonction transformant une donnee en un entier de taille fixe servant d'indice.
Exemple : hash('bonjour') retourne un entier, puis % taille donne l'indice.
Collision
Situation ou deux clés differentes produisent le meme indice apres hachage.
Exemple : hash('ab') % 10 == hash('ba') % 10.
Facteur de charge
Rapport nombre d'éléments / taille du tableau. Declenche un redimensionnement s'il depasse un seuil.
Exemple : Facteur de charge > 0.75 : redimensionnement du tableau.

Formules essentielles

Calcul de l'indice : indice = hash(clé) % taille_tableauConditions : clé immuable et hachable
Facteur de charge : alpha = n / taille_tableauConditions : n = nombre d'éléments, seuil usuel 0.75
Complexite moyenne : O(1) pour recherche, insertion, suppressionConditions : Bonne fonction de hachage et facteur de charge faible
Complexite pire cas : O(n)Conditions : Toutes les clés collisionnent (meme indice)

Méthodes types

résoudre un exercice de table de hachage

  1. Calculer l'indice pour chaque clé : hash(clé) % taille
  2. Placer chaque clé dans la table a l'indice calcule
  3. En cas de collision, appliquer la strategie demandee (chainage ou sondage)
  4. Calculer le facteur de charge : nb_elements / taille
  5. vérifier si redimensionnement nécessaire (facteur > 0.75)

Comptage d'occurrences avec un dict

  1. Creer un dictionnaire vide
  2. Parcourir la sequence
  3. Pour chaque élément : dict[elem] = dict.get(elem, 0) + 1
  4. Le dictionnaire contient les comptages

Pièges fréquents à éviter

  • Les listes Python ne sont pas hachables : on ne peut pas les utiliser comme clés de dictionnaire.
  • O(1) est une complexite en moyenne, pas dans le pire cas.
  • Le dictionnaire Python conserve l'ordre d'insertion mais ce n'est pas un tri.
  • Ne pas confondre hash (hachage pour stockage) et chiffrement (securite).
  • table = [[]] * n cree n references vers la MEME liste, utiliser [[] for _ in range(n)].

QCM gratuit (3 questions sur 20+)

1. Quelle est la complexite moyenne de recherche dans une table de hachage ?

2. Qu'est-ce qu'une collision dans une table de hachage ?

3. Quel type Python ne peut PAS etre une clé de dictionnaire ?

Inscris-toi pour voir les 20+ questions du QCM et les corrections détaillées.

S'inscrire

Comment réviser efficacement ce chapitre ?

  1. 1
    Étape 1 — Lire le cours45 min

    Parcours le cours complet de Dictionnaires et tables de hachage en prenant des notes synthétiques. Identifie 5-10 notions clés.

  2. 2
    Étape 2 — Construire la fiche45 min

    Résume sur 1 page : définitions, formules, schémas et exemples-clés.

  3. 3
    Étape 3 — Tester ta compréhension30 min

    Fais le QCM intégral (20+ questions) et identifie les notions encore floues.

  4. 4
    Étape 4 — Annales en conditions réelles1h30

    Refais 2-3 exercices types Bac chronométrés pour maîtriser la rédaction attendue.

Questions fréquentes sur Dictionnaires et tables de hachage

Comment réviser efficacement Dictionnaires et tables de hachage en NSI ?

Pour bien maîtriser Dictionnaires et tables de hachage, suis cette méthode en 4 étapes : (1) lis le cours complet en prenant des notes synthétiques, (2) résume sur 1 page en isolant les notions clés et formules, (3) entraîne-toi sur 10-15 QCM corrigés pour vérifier ta compréhension, (4) refais 1-2 exercices types Bac en conditions chronométrées. FlashBac propose pour ce chapitre les 4 ressources dans une interface unifiée.

Quelles sont les notions essentielles de Dictionnaires et tables de hachage ?

Les notions clés de Dictionnaires et tables de hachage sont définies par le programme officiel BO 2024 de NSI. Notre cours FlashBac suit fidèlement les attendus du Bulletin Officiel et a été relu par des professeurs certifiés ou agrégés en exercice. Tu retrouves la liste précise des notions dans le sommaire du cours et dans la fiche de révision synthétique.

Dictionnaires et tables de hachage peut-il tomber au Bac 2026 ?

Oui, Dictionnaires et tables de hachage fait partie du programme officiel NSI pour le Bac 2026. C'est l'un des chapitres pouvant être évalué dans les épreuves de spécialité (Bac) ou les épreuves finales (Brevet). Refais les annales des 3-5 dernières années pour identifier les types de questions classiques sur ce chapitre.

Combien de temps faut-il pour maîtriser Dictionnaires et tables de hachage ?

Compte en moyenne 4 à 6 heures de travail pour maîtriser un chapitre comme Dictionnaires et tables de hachage : 1h pour la lecture du cours, 1h pour la fiche de révision, 2-3h pour les exercices et QCM. Si tu utilises les Profs IA FlashBac, tu peux poser des questions ciblées et accélérer considérablement la compréhension.

Comment FlashBac t'aide à réviser Dictionnaires et tables de hachage ?

Sur FlashBac, tu accèdes pour Dictionnaires et tables de hachage : (1) le cours complet conforme BO 2024, (2) une fiche de révision synthétique imprimable, (3) un QCM corrigé avec explications détaillées, (4) des exercices types Bac avec corrigés étape par étape, (5) des flashcards de mémorisation espacée, (6) un Prof IA spécialisé en NSI disponible 24/7. Inscription gratuite pour 1 matière, plan Premium 10,99 €/mois (ou 99€/an, 3 mois offerts) avec accès complet.

Tu as lu le cours — passe à la pratique

Le cours et la fiche sont en accès libre. Mais lire ne suffit pas à retenir : pour ancrer Dictionnaires et tables de hachage, entraîne-toi avec le QCM corrigé complet, les exercices types, les flashcards de mémorisation et ton Prof IA spécialisé (24h/24). Inscription gratuite ; Premium 10,99 €/mois (ou 99€/an, 3 mois offerts) pour tout débloquer.

Chapitre précédent
Structures lineaires : listes, piles, files
Chapitre suivant
Arbres binaires et arbres binaires de recherche

Autres chapitres de NSI

Ressources complémentaires