bg_image
header

Hash Tabelle

Eine Hash-Map (auch Hash-Tabelle genannt) ist eine Datenstruktur, die verwendet wird, um Schlüssel-Wert-Paare effizient zu speichern und darauf zuzugreifen. Sie bietet durchschnittlich konstante Zeitkomplexität (O(1)) für Such-, Einfüge- und Löschoperationen. Hier sind die grundlegenden Konzepte und Funktionsweisen einer Hash-Map:

Grundprinzipien einer Hash-Map

  1. Schlüssel-Wert-Paare: Eine Hash-Map speichert Daten in Form von Schlüssel-Wert-Paaren. Jeder Schlüssel ist eindeutig und wird verwendet, um auf den zugehörigen Wert zuzugreifen.
  2. Hash-Funktion: Eine Hash-Funktion nimmt einen Schlüssel und wandelt ihn in einen Index um, der auf einen bestimmten Speicherort (Bucket) in der Hash-Map verweist. Diese Funktion sollte idealerweise eine gleichmäßige Verteilung der Schlüssel auf die Buckets gewährleisten, um Kollisionen zu minimieren.
  3. Buckets: Ein Bucket ist ein Speicherort in der Hash-Map, an dem Schlüssel-Wert-Paare gespeichert werden. Ein Bucket kann mehrere Paare enthalten, insbesondere wenn Kollisionen auftreten.

Kollisionen und ihre Behandlung

Kollisionen treten auf, wenn zwei unterschiedliche Schlüssel denselben Hash-Wert und damit denselben Bucket erzeugen. Es gibt mehrere Methoden zur Behandlung von Kollisionen:

  1. Verkettung (Chaining): Jeder Bucket enthält eine Liste (oder eine andere Datenstruktur), in der alle Schlüssel-Wert-Paare, die denselben Hash-Wert haben, gespeichert werden. Bei einer Kollision wird das neue Paar einfach zur Liste des entsprechenden Buckets hinzugefügt.
  2. Offene Adressierung (Open Addressing): Alle Schlüssel-Wert-Paare werden direkt im Array der Hash-Map gespeichert. Bei einer Kollision wird nach einem anderen freien Bucket gesucht (durch Probeverfahren wie lineares Sondieren, quadratisches Sondieren oder Double Hashing).

Vorteile einer Hash-Map

  • Schnelle Zugriffszeiten: Dank der Hash-Funktion sind Such-, Einfüge- und Löschoperationen in durchschnittlicher konstanter Zeit möglich.
  • Flexibilität: Hash-Maps können eine Vielzahl von Datentypen als Schlüssel und Werte speichern.

Nachteile einer Hash-Map

  • Speicherverbrauch: Hash-Maps können mehr Speicher benötigen, insbesondere wenn viele Kollisionen auftreten und lange Listen in den Buckets entstehen oder bei offener Adressierung viele leere Buckets vorhanden sind.
  • Kollisionen: Kollisionen können die Leistung beeinträchtigen, besonders wenn die Hash-Funktion nicht gut entworfen ist oder die Hash-Map nicht ausreichend dimensioniert ist.
  • Nicht geordnet: Hash-Maps behalten keine Ordnung der Schlüssel bei. Wenn eine geordnete Datenstruktur benötigt wird, wie z.B. bei der Iteration in einer bestimmten Reihenfolge, ist eine Hash-Map nicht die beste Wahl.

Implementierungsbeispiel (in Python)

Hier ist ein einfaches Beispiel einer Hash-Map-Implementierung in Python:

class HashMap:
    def __init__(self, size=10):
        self.size = size
        self.map = [[] for _ in range(size)]
        
    def _get_hash(self, key):
        return hash(key) % self.size
    
    def add(self, key, value):
        key_hash = self._get_hash(key)
        key_value = [key, value]
        
        for pair in self.map[key_hash]:
            if pair[0] == key:
                pair[1] = value
                return True
        
        self.map[key_hash].append(key_value)
        return True
    
    def get(self, key):
        key_hash = self._get_hash(key)
        for pair in self.map[key_hash]:
            if pair[0] == key:
                return pair[1]
        return None
    
    def delete(self, key):
        key_hash = self._get_hash(key)
        for pair in self.map[key_hash]:
            if pair[0] == key:
                self.map[key_hash].remove(pair)
                return True
        return False
    
# Beispiel der Nutzung
h = HashMap()
h.add("key1", "value1")
h.add("key2", "value2")
print(h.get("key1"))  # Ausgabe: value1
h.delete("key1")
print(h.get("key1"))  # Ausgabe: None

Zusammengefasst ist eine Hash-Map eine äußerst effiziente und vielseitige Datenstruktur, die besonders für Szenarien geeignet ist, in denen schnelle Zugriffszeiten auf Daten benötigt werden.