Menu
Coddy logo textTech

Hash Map

Zuletzt aktualisiert

Eine Hash Map speichert Schlüssel-Wert-Paare und erlaubt es, einen Wert per Schlüssel im Durchschnitt in O(1) nachzuschlagen. Sie funktioniert genau wie eine Hashtabelle, aber jeder Bucket-Eintrag trägt sowohl einen Schlüssel als auch seinen zugehörigen Wert. Um ein Paar zu speichern oder abzurufen, wird der Schlüssel auf einen Bucket-Index gehasht, dann wird die Kette dieses Buckets nach dem passenden Schlüssel durchsucht. Drücke oben auf Abspielen, um zu sehen, wie Paare nach gehashtem Bucket platziert und ein Wert per Schlüssel abgerufen wird.

Das ist die Struktur hinter Pythons dict, Javas HashMap und JavaScripts Map/Objekten. Kollisionen werden genauso behandelt wie in einer Hashtabelle - hier durch separate Verkettung - daher hängt die Leistung von einer guten Hash-Funktion und einem niedrigen Füllfaktor ab.

Zeitkomplexität

OperationDurchschnittSchlechtester Fall
Einfügen/aktualisieren (put)O(1)O(n)
Nachschlagen (get)O(1)O(n)
LöschenO(1)O(n)
SpeicherO(n)O(n)

Hash Map in gängigen Sprachen

SpracheTyp
Pythondict
JavaHashMap
JavaScriptMap / Objekt
C++std::unordered_map
Gomap

Durchgerechnetes Beispiel

Einfügen der Paare ("cat", 3), ("dog", 5), ("cat", 9), ("emu", 7) in eine Map mit 8 Buckets, mit hash(key) % 8. Angenommen hash("cat") % 8 = 2, hash("dog") % 8 = 5, hash("emu") % 8 = 2:

SchrittStrukturAktion
Put ("cat", 3)Bucket 2: [("cat", 3)]Hasht auf Bucket 2; Kette leer, also wird das Paar angehängt.
Put ("dog", 5)Bucket 2: [("cat", 3)], Bucket 5: [("dog", 5)]Hasht auf Bucket 5; Kette leer, also wird das Paar angehängt.
Put ("cat", 9)Bucket 2: [("cat", 9)], Bucket 5: [("dog", 5)]Hasht auf Bucket 2; Schlüssel "cat" ist bereits in der Kette, also wird sein Wert auf 9 aktualisiert.
Put ("emu", 7)Bucket 2: [("cat", 9), ("emu", 7)], Bucket 5: [("dog", 5)]Hasht auf Bucket 2; kollidiert mit "cat", Schlüssel nicht gefunden, also wird das Paar angehängt.
Get "emu"Bucket 2: [("cat", 9), ("emu", 7)]Hasht auf Bucket 2; durchsucht die Kette, überspringt "cat", trifft "emu", gibt 7 zurück.

Wann eine Hash Map verwenden

Verwenden, wennVermeiden, wenn
Du im Durchschnitt O(1)-Nachschlagen, -Einfügen und -Löschen per exaktem Schlüssel brauchst.Du Schlüssel sortiert halten oder Bereichsabfragen brauchst - nutze einen balancierten BST oder eine sortierte Map.
Schlüssel hashbar sind und Gleichheit wohldefiniert ist (Strings, Ints, Tupel).Schlüssel veränderlich sind und sich nach dem Einfügen ändern können, was ihren Bucket verfälscht.
Du nach einem Bezeichner zählst, dedupliziert, cachst oder indexierst.Du Worst-Case-O(log n)-Garantien statt amortisierter Durchschnittsschranken brauchst.
Die Iterationsreihenfolge egal ist oder eine einfügereihenfolge-Map genügt.Der Speicher sehr knapp ist - Buckets, Füllfaktor-Spielraum und Zeiger verursachen Overhead.

Hash Map-Code

Eine saubere, lauffähige Hash Map-Implementierung in Python, JavaScript, Java, C++, C. Wähle eine Sprache, kopiere den Code oder öffne ihn vorgeladen im Coddy-Playground.

Hash Map-Code in Python

Python
1# Python's built-in dict is a hash map: O(1) average2# insert, lookup, and delete.3inventory = {"apple": 3, "banana": 7}4
5# Insert and update6inventory["cherry"] = 57inventory["apple"] += 28
9# Lookup, with .get for a safe default on missing keys10print("apple: ", inventory["apple"])11print("mango: ", inventory.get("mango", 0))12
13# Membership test and delete14print("banana in stock:", "banana" in inventory)15del inventory["banana"]16print("banana in stock:", "banana" in inventory)17
18# Iterate over key-value pairs19for fruit, count in sorted(inventory.items()):20    print(f"{fruit}: {count}")21
22# Classic hash map use case: counting frequencies23words = "the quick brown fox jumps over the lazy dog the end".split()24freq = {}25for word in words:26    freq[word] = freq.get(word, 0) + 127
28print("Occurrences of the:", freq["the"])29print("Most common word:  ", max(freq, key=freq.get))
Führe diesen Code im Python-Playground aus

Hash-Map-FAQ

Was ist der Unterschied zwischen einer Hash Map und einer Hashtabelle?
Sie sind im Wesentlichen dieselbe Struktur - ein Array von Buckets, das über einen Hash des Schlüssels adressiert wird. Im allgemeinen Sprachgebrauch bezeichnet "Hashtabelle" oft eine Menge von Schlüsseln oder die allgemeine Technik, während "Hash Map" das Speichern von Schlüssel-Wert-Paaren betont. Manche Sprachen ziehen auch eine Thread-Sicherheits-Unterscheidung (z. B. Hashtable vs HashMap in Java), aber der Kernalgorithmus ist identisch.
Wie ist die Zeitkomplexität einer Hash Map?
Put, get und delete sind im Durchschnitt O(1) mit einer guten Hash-Funktion und einem niedrigen Füllfaktor. Im pathologischen Fall, in dem alle Schlüssel in einen einzigen Bucket kollidieren, degenerieren sie zu O(n), weshalb Vergrößern und gutes Hashing wichtig sind.
Wie behandelt eine Hash Map zwei Schlüssel, die auf denselben Bucket hashen?
Sie löst die Kollision auf. Diese Visualisierung verwendet separate Verkettung: Jeder Bucket enthält eine kleine Liste, und ein neues Paar, dessen Schlüssel dorthin hasht, wird an diese Liste angehängt. Beim Nachschlagen durchsucht die Map die kurze Kette nach dem passenden Schlüssel. Die alternative Technik ist offene Adressierung, die einen anderen Slot im Array sondiert.
Hash Map vs. binärer Suchbaum: Was sollte ich verwenden?
Verwende eine Hash Map, wenn du nur Nachschlagen per exaktem Schlüssel brauchst und O(1)-Durchschnittsoperationen willst. Verwende einen balancierten binären Suchbaum (wie TreeMap oder std::map), wenn du sortierte Schlüssel, Bereichsabfragen oder Vorgänger-/Nachfolgersuchen brauchst, die O(log n) kosten. Der BST tauscht etwas Geschwindigkeit gegen Ordnungsgarantien, die eine Hash Map nicht bieten kann.
Was ist der Füllfaktor und warum löst er ein Vergrößern aus?
Der Füllfaktor ist das Verhältnis der gespeicherten Einträge zu den Buckets. Steigt er, werden die Ketten länger und durchschnittliche Nachschlagevorgänge langsamer, daher vergrößern die meisten Implementierungen (typischerweise Verdopplung der Buckets und erneutes Hashen von allem), sobald er einen Schwellenwert wie 0.75 überschreitet. Das Vergrößern ist O(n), aber selten, daher wird es amortisiert und hält Durchschnittsoperationen bei O(1).
Kann ich ein veränderliches Objekt wie eine Liste als Hash-Map-Schlüssel verwenden?
Normalerweise nein. Schlüssel müssen hashbar sein und ihr Hash muss konstant bleiben, solange sie in der Map sind - Python wirft z. B. TypeError: unhashable type für eine list. Wenn du einen Schlüssel nach dem Einfügen veränderst, ändert sich sein Hash und die Map findet ihn nicht mehr im richtigen Bucket und verliert den Eintrag stillschweigend. Verwende unveränderliche Schlüssel wie Strings, Zahlen oder Tupel.
Coddy programming languages illustration

Meistere Algorithmen mit Coddy

LOS GEHT'S