Hashing I Datenstrukturen und Algorithmen Vorlesung 12: Hashing Prof. Dr. Erika Ábrahám Theorie Hybrider Systeme Informatik 2 http://ths.rwth-aachen.de/teaching/ss-14/ datenstrukturen-und-algorithmen/ Diese Präsentation verwendet in Teilen Folien von Joost-Pieter Katoen. 02. Juni 2014 Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 1/53 Hashing I Übersicht 1 Direkte Adressierung 2 Grundlagen des Hashings 3 Kollisionsauflösung durch Verkettung 4 Hashfunktionen Divisionsmethode Multiplikationsmethode Universelles Hashing 5 Offene Adressierung Lineares Sondieren Quadratisches Sondieren Doppeltes Hashing Effizienz der offenen Adressierung Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 2/53 Hashing I Einführung Dictionary (Wörterbuch) Das Dictionary (auch: Map, assoziatives Array) speichert Informationen, die jederzeit anhand ihres Schlüssels abgerufen werden können. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 3/53 Hashing I Einführung Dictionary (Wörterbuch) Das Dictionary (auch: Map, assoziatives Array) speichert Informationen, die jederzeit anhand ihres Schlüssels abgerufen werden können. Weiterhin: I Die Daten sind dynamisch gespeichert. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 3/53 Hashing I Einführung Dictionary (Wörterbuch) Das Dictionary (auch: Map, assoziatives Array) speichert Informationen, die jederzeit anhand ihres Schlüssels abgerufen werden können. Weiterhin: I Die Daten sind dynamisch gespeichert. I Element dictSearch(Dict d, int k) gibt die in d zum Schlüssel k gespeicherten Informationen zurück. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 3/53 Hashing I Einführung Dictionary (Wörterbuch) Das Dictionary (auch: Map, assoziatives Array) speichert Informationen, die jederzeit anhand ihres Schlüssels abgerufen werden können. Weiterhin: I Die Daten sind dynamisch gespeichert. I Element dictSearch(Dict d, int k) gibt die in d zum Schlüssel k gespeicherten Informationen zurück. I void dictInsert(Dict d, Element e) speichert Element e unter seinem Schlüssel e.key in d. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 3/53 Hashing I Einführung Dictionary (Wörterbuch) Das Dictionary (auch: Map, assoziatives Array) speichert Informationen, die jederzeit anhand ihres Schlüssels abgerufen werden können. Weiterhin: I Die Daten sind dynamisch gespeichert. I Element dictSearch(Dict d, int k) gibt die in d zum Schlüssel k gespeicherten Informationen zurück. I void dictInsert(Dict d, Element e) speichert Element e unter seinem Schlüssel e.key in d. I void dictDelete(Dict d, Element e) löscht das Element e aus d, wobei e in d enthalten sein muss. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 3/53 Hashing I Einführung Dictionary (Wörterbuch) Das Dictionary (auch: Map, assoziatives Array) speichert Informationen, die jederzeit anhand ihres Schlüssels abgerufen werden können. Weiterhin: I Die Daten sind dynamisch gespeichert. I Element dictSearch(Dict d, int k) gibt die in d zum Schlüssel k gespeicherten Informationen zurück. I void dictInsert(Dict d, Element e) speichert Element e unter seinem Schlüssel e.key in d. I void dictDelete(Dict d, Element e) löscht das Element e aus d, wobei e in d enthalten sein muss. Beispiel Symboltabelle eines Compilers, wobei die Schlüssel Strings (etwa Bezeichner) sind. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 3/53 Hashing I Einführung Problem Welche Datenstrukturen sind geeignet, um ein Dictionary zu implementieren? Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 4/53 Hashing I Einführung Problem Welche Datenstrukturen sind geeignet, um ein Dictionary zu implementieren? I Heap: Einfügen und Löschen sind effizient. Aber was ist mit Suche? Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 4/53 Hashing I Einführung Problem Welche Datenstrukturen sind geeignet, um ein Dictionary zu implementieren? I Heap: Einfügen und Löschen sind effizient. Aber was ist mit Suche? I Sortiertes Array/Liste: Einfügen ist im Worst-Case linear. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 4/53 Hashing I Einführung Problem Welche Datenstrukturen sind geeignet, um ein Dictionary zu implementieren? I Heap: Einfügen und Löschen sind effizient. Aber was ist mit Suche? I Sortiertes Array/Liste: Einfügen ist im Worst-Case linear. I Rot-Schwarz-Baum: Alle Operationen sind im Worst-Case logarithmisch. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 4/53 Hashing I Einführung Problem Welche Datenstrukturen sind geeignet, um ein Dictionary zu implementieren? I Heap: Einfügen und Löschen sind effizient. Aber was ist mit Suche? I Sortiertes Array/Liste: Einfügen ist im Worst-Case linear. I Rot-Schwarz-Baum: Alle Operationen sind im Worst-Case logarithmisch. Lösung Unter realistischen Annahmen benötigt eine Hashtabelle im Durchschnitt O(1) für die Operationen Einfügen, Löschen und Suchen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 4/53 Hashing I Direkte Adressierung Übersicht 1 Direkte Adressierung 2 Grundlagen des Hashings 3 Kollisionsauflösung durch Verkettung 4 Hashfunktionen Divisionsmethode Multiplikationsmethode Universelles Hashing 5 Offene Adressierung Lineares Sondieren Quadratisches Sondieren Doppeltes Hashing Effizienz der offenen Adressierung Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 5/53 Hashing I Direkte Adressierung Direkte Adressierung Direkte Adressierung I Alloziere ein Array (die Direkte-Adressierungs-Tabelle), so dass es für jeden möglichen Schlüssel eine(1) Position gibt. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 6/53 Hashing I Direkte Adressierung Direkte Adressierung Direkte Adressierung I I Alloziere ein Array (die Direkte-Adressierungs-Tabelle), so dass es für jeden möglichen Schlüssel eine(1) Position gibt. Jedes Array-Element enthält einen Pointer auf die gespeicherte Information. I Der Einfachheit halber vernachlässigen wir in der Vorlesung die zu den Schlüsseln gehörenden Informationen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 6/53 Hashing I Direkte Adressierung Direkte Adressierung Direkte Adressierung I I Alloziere ein Array (die Direkte-Adressierungs-Tabelle), so dass es für jeden möglichen Schlüssel eine(1) Position gibt. Jedes Array-Element enthält einen Pointer auf die gespeicherte Information. I I Der Einfachheit halber vernachlässigen wir in der Vorlesung die zu den Schlüsseln gehörenden Informationen. Mit Schlüsselmenge U = {0, 1, . . . , N − 1} ergibt sich: I Eine Direkte-Adressierungs-Tabelle T[0..N-1], wobei T[k] zu Schlüssel k gehört. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 6/53 Hashing I Direkte Adressierung Direkte Adressierung Direkte Adressierung I I Alloziere ein Array (die Direkte-Adressierungs-Tabelle), so dass es für jeden möglichen Schlüssel eine(1) Position gibt. Jedes Array-Element enthält einen Pointer auf die gespeicherte Information. I I Der Einfachheit halber vernachlässigen wir in der Vorlesung die zu den Schlüsseln gehörenden Informationen. Mit Schlüsselmenge U = {0, 1, . . . , N − 1} ergibt sich: I I Eine Direkte-Adressierungs-Tabelle T[0..N-1], wobei T[k] zu Schlüssel k gehört. datSearch(T, int k): return T[k]; Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 6/53 Hashing I Direkte Adressierung Direkte Adressierung Direkte Adressierung I I Alloziere ein Array (die Direkte-Adressierungs-Tabelle), so dass es für jeden möglichen Schlüssel eine(1) Position gibt. Jedes Array-Element enthält einen Pointer auf die gespeicherte Information. I I Der Einfachheit halber vernachlässigen wir in der Vorlesung die zu den Schlüsseln gehörenden Informationen. Mit Schlüsselmenge U = {0, 1, . . . , N − 1} ergibt sich: I I I Eine Direkte-Adressierungs-Tabelle T[0..N-1], wobei T[k] zu Schlüssel k gehört. datSearch(T, int k): return T[k]; datInsert(T, Element e): T[e.key] = e; Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 6/53 Hashing I Direkte Adressierung Direkte Adressierung Direkte Adressierung I I Alloziere ein Array (die Direkte-Adressierungs-Tabelle), so dass es für jeden möglichen Schlüssel eine(1) Position gibt. Jedes Array-Element enthält einen Pointer auf die gespeicherte Information. I I Der Einfachheit halber vernachlässigen wir in der Vorlesung die zu den Schlüsseln gehörenden Informationen. Mit Schlüsselmenge U = {0, 1, . . . , N − 1} ergibt sich: I I I I Eine Direkte-Adressierungs-Tabelle T[0..N-1], wobei T[k] zu Schlüssel k gehört. datSearch(T, int k): return T[k]; datInsert(T, Element e): T[e.key] = e; datDelete(T, Element e): T[e.key] = null; Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 6/53 Hashing I Direkte Adressierung Direkte Adressierung Direkte Adressierung I I Alloziere ein Array (die Direkte-Adressierungs-Tabelle), so dass es für jeden möglichen Schlüssel eine(1) Position gibt. Jedes Array-Element enthält einen Pointer auf die gespeicherte Information. I I Mit Schlüsselmenge U = {0, 1, . . . , N − 1} ergibt sich: I I I I I Der Einfachheit halber vernachlässigen wir in der Vorlesung die zu den Schlüsseln gehörenden Informationen. Eine Direkte-Adressierungs-Tabelle T[0..N-1], wobei T[k] zu Schlüssel k gehört. datSearch(T, int k): return T[k]; datInsert(T, Element e): T[e.key] = e; datDelete(T, Element e): T[e.key] = null; Die Laufzeit jeder Operation ist im Worst-Case Θ(1). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 6/53 Hashing I Direkte Adressierung Direkte Adressierung Direkte-Adressierungs-Tabelle T Schlüssel 0 U 1 0 2 4 1 6 3 K 2 4 7 5 6 3 9 5 7 8 8 9 benutzte Schlüssel n = 10 Schlüsselmenge Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 7/53 Hashing I Direkte Adressierung Beispielanwendungen Beispielanwendung: Counting Sort verwendet direkte Adressierung um die Schlüsselhäufigkeiten zu speichern. Eine andere Anwendung: Duplikate in Linearzeit erkennen. Gegeben seien n ganzzahlige Schlüssel zwischen 0 und m − 1 (m ∈ Θ(n)) in einem Array E . 1 2 3 4 5 6 7 8 9 10 11 bool checkDuplicates(int[] E, int n, int m) { int histogram[m] = 0; // "Direkte-Adressierungs-Tabelle" for (int i = 0; i < n; i++) { if (histogram[E[i]] > 0) { return true; // Duplikat gefunden } else { histogram[E[i]]++; // Zähle Häufigkeit } } return false; // keine Duplikate } Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 8/53 Hashing I Direkte Adressierung Nachteile der direkten Adressierung Hauptproblem: Übermäßiger Speicherbedarf für das Array. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 9/53 Hashing I Direkte Adressierung Nachteile der direkten Adressierung Hauptproblem: Übermäßiger Speicherbedarf für das Array. I Zum Beispiel bei Strings mit 20 Zeichen (5 bit/Zeichen) als Schlüssel benötigt man 25·20 = 2100 Arrayeinträge. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 9/53 Hashing I Direkte Adressierung Nachteile der direkten Adressierung Hauptproblem: Übermäßiger Speicherbedarf für das Array. I Zum Beispiel bei Strings mit 20 Zeichen (5 bit/Zeichen) als Schlüssel benötigt man 25·20 = 2100 Arrayeinträge. I Können wir diesen riesigen Speicherbedarf vermeiden und effizient bleiben? Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 9/53 Hashing I Direkte Adressierung Nachteile der direkten Adressierung Hauptproblem: Übermäßiger Speicherbedarf für das Array. I Zum Beispiel bei Strings mit 20 Zeichen (5 bit/Zeichen) als Schlüssel benötigt man 25·20 = 2100 Arrayeinträge. I Können wir diesen riesigen Speicherbedarf vermeiden und effizient bleiben? Ja! – mit Hashing. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 9/53 Hashing I Grundlagen des Hashings Übersicht 1 Direkte Adressierung 2 Grundlagen des Hashings 3 Kollisionsauflösung durch Verkettung 4 Hashfunktionen Divisionsmethode Multiplikationsmethode Universelles Hashing 5 Offene Adressierung Lineares Sondieren Quadratisches Sondieren Doppeltes Hashing Effizienz der offenen Adressierung Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 10/53 Hashing I Grundlagen des Hashings Hashing Praktisch wird nur ein kleiner Teil der Schlüssel verwendet, d. h. |K | |U|. ⇒ Bei direkter Adressierung ist der größte Teil von T verschwendet. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 11/53 Hashing I Grundlagen des Hashings Hashing Praktisch wird nur ein kleiner Teil der Schlüssel verwendet, d. h. |K | |U|. ⇒ Bei direkter Adressierung ist der größte Teil von T verschwendet. Das Ziel von Hashing ist: I Einen extrem großen Schlüsselraum auf einen vernünftig kleinen Bereich von ganzen Zahlen abzubilden. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 11/53 Hashing I Grundlagen des Hashings Hashing Praktisch wird nur ein kleiner Teil der Schlüssel verwendet, d. h. |K | |U|. ⇒ Bei direkter Adressierung ist der größte Teil von T verschwendet. Das Ziel von Hashing ist: I Einen extrem großen Schlüsselraum auf einen vernünftig kleinen Bereich von ganzen Zahlen abzubilden. I Dass zwei Schlüssel auf die selbe Zahl abgebildet werden, soll möglichst unwahrscheinlich sein. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 11/53 Hashing I Grundlagen des Hashings Hashing Praktisch wird nur ein kleiner Teil der Schlüssel verwendet, d. h. |K | |U|. ⇒ Bei direkter Adressierung ist der größte Teil von T verschwendet. Das Ziel von Hashing ist: I Einen extrem großen Schlüsselraum auf einen vernünftig kleinen Bereich von ganzen Zahlen abzubilden. I Dass zwei Schlüssel auf die selbe Zahl abgebildet werden, soll möglichst unwahrscheinlich sein. Hashfunktion, Hashtabelle, Hashkollision Eine Hashfunktion bildet Schlüssel auf Indices der Hashtabelle T ab: h : U −→ { 0, 1, . . . , m−1 } für Tabellengröße m. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 11/53 Hashing I Grundlagen des Hashings Hashing Praktisch wird nur ein kleiner Teil der Schlüssel verwendet, d. h. |K | |U|. ⇒ Bei direkter Adressierung ist der größte Teil von T verschwendet. Das Ziel von Hashing ist: I Einen extrem großen Schlüsselraum auf einen vernünftig kleinen Bereich von ganzen Zahlen abzubilden. I Dass zwei Schlüssel auf die selbe Zahl abgebildet werden, soll möglichst unwahrscheinlich sein. Hashfunktion, Hashtabelle, Hashkollision Eine Hashfunktion bildet Schlüssel auf Indices der Hashtabelle T ab: h : U −→ { 0, 1, . . . , m−1 } für Tabellengröße m. Wir sagen, dass h(k) der Hashwert des Schlüssels k ist. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 11/53 Hashing I Grundlagen des Hashings Hashing Praktisch wird nur ein kleiner Teil der Schlüssel verwendet, d. h. |K | |U|. ⇒ Bei direkter Adressierung ist der größte Teil von T verschwendet. Das Ziel von Hashing ist: I Einen extrem großen Schlüsselraum auf einen vernünftig kleinen Bereich von ganzen Zahlen abzubilden. I Dass zwei Schlüssel auf die selbe Zahl abgebildet werden, soll möglichst unwahrscheinlich sein. Hashfunktion, Hashtabelle, Hashkollision Eine Hashfunktion bildet Schlüssel auf Indices der Hashtabelle T ab: h : U −→ { 0, 1, . . . , m−1 } für Tabellengröße m. Wir sagen, dass h(k) der Hashwert des Schlüssels k ist. Das Auftreten von h(k) = h(k 0 ) für k 6= k 0 nennt man eine Kollision. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 11/53 Hashing I Grundlagen des Hashings Hashing Praktisch wird nur ein kleiner Teil der Schlüssel verwendet, d. h. |K | |U|. ⇒ Bei direkter Adressierung ist der größte Teil von T verschwendet. Das Ziel von Hashing ist: I Einen extrem großen Schlüsselraum auf einen vernünftig kleinen Bereich von ganzen Zahlen abzubilden. I Dass zwei Schlüssel auf die selbe Zahl abgebildet werden, soll möglichst unwahrscheinlich sein. Hashfunktion, Hashtabelle, Hashkollision Eine Hashfunktion bildet Schlüssel auf Indices der Hashtabelle T ab: h : U −→ { 0, 1, . . . , m−1 } für Tabellengröße m. Wir sagen, dass h(k) der Hashwert des Schlüssels k ist. Das Auftreten von h(k) = h(k 0 ) für k 6= k 0 nennt man eine Kollision. Example: Bucket Sort, Klausurregistrierung mit Matrikelnummern Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 11/53 Hashing I Grundlagen des Hashings Example: Klausurregistrierung mit Matrikelnummern I Identifiziere Studenten über Matrikelnummern. I 106 mögliche Matrikelnummern. I In dieser Vorlesung: 600 Studenten. I Finde eine Funktion h : [0, 106 − 1] −→ [0, 599] , die alle Matrikenummern aus [0, 106 − 1] möglichst gleichverteilt auf Werte in [0, 599] abbildet. I Zum Beispiel: modulo 600. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 12/53 Hashing I Grundlagen des Hashings Hashing Schlüsselmenge Hashfunktion 0 Hashtabelle U K k2 k4 h(k1 ) h(k2 ) = h(k3 ) k1 h(k5 ) k3 k5 Kollision h(k4 ) m−1 benutzte Schlüssel Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 13/53 Hashing I Grundlagen des Hashings Hashing Schlüsselmenge Hashfunktion 0 Hashtabelle U K k2 k4 h(k1 ) h(k2 ) = h(k3 ) k1 h(k5 ) k3 k5 Kollision h(k4 ) m−1 benutzte Schlüssel I Wie finden wir Hashfunktionen, die einfach auszurechnen sind und Kollisionen minimieren? Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 13/53 Hashing I Grundlagen des Hashings Hashing Schlüsselmenge Hashfunktion 0 Hashtabelle U K k2 k4 h(k1 ) h(k2 ) = h(k3 ) k1 h(k5 ) k3 k5 Kollision h(k4 ) m−1 benutzte Schlüssel I I Wie finden wir Hashfunktionen, die einfach auszurechnen sind und Kollisionen minimieren? Wie behandeln wir dennoch auftretende Kollisionen? Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 13/53 Hashing I Grundlagen des Hashings Kollisionen: Das Geburtstagsparadoxon Unsere Hashfunktion mag noch so gut sein, wir sollten auf Kollisionen vorbereitet sein! Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 14/53 Hashing I Grundlagen des Hashings Kollisionen: Das Geburtstagsparadoxon Unsere Hashfunktion mag noch so gut sein, wir sollten auf Kollisionen vorbereitet sein! Das liegt am Geburtstagsparadoxon Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 14/53 Hashing I Grundlagen des Hashings Kollisionen: Das Geburtstagsparadoxon Unsere Hashfunktion mag noch so gut sein, wir sollten auf Kollisionen vorbereitet sein! Das liegt am Geburtstagsparadoxon I Die Wahrscheinlichkeit, dass dein Nachbar am selben Tag wie du 1 Geburtstag hat ist 365 ≈ 0,027. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 14/53 Hashing I Grundlagen des Hashings Kollisionen: Das Geburtstagsparadoxon Unsere Hashfunktion mag noch so gut sein, wir sollten auf Kollisionen vorbereitet sein! Das liegt am Geburtstagsparadoxon I Die Wahrscheinlichkeit, dass dein Nachbar am selben Tag wie du 1 Geburtstag hat ist 365 ≈ 0,027. I Fragt man 23 Personen, wächst die Wahrscheinlichkeit auf 23 365 ≈ 0,063. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 14/53 Hashing I Grundlagen des Hashings Kollisionen: Das Geburtstagsparadoxon Unsere Hashfunktion mag noch so gut sein, wir sollten auf Kollisionen vorbereitet sein! Das liegt am Geburtstagsparadoxon I Die Wahrscheinlichkeit, dass dein Nachbar am selben Tag wie du 1 Geburtstag hat ist 365 ≈ 0,027. I Fragt man 23 Personen, wächst die Wahrscheinlichkeit auf 23 365 ≈ 0,063. I Sind aber 23 Personen in einem Raum, dann haben zwei von ihnen den selben Geburtstag mit Wahrscheinlichkeit 1− Prof. Dr. Erika Ábrahám 365 364 363 343 · · · ... · 365 365 365 365 ≈ 0,5 Datenstrukturen und Algorithmen 14/53 Hashing I Grundlagen des Hashings Kollisionen: Das Geburtstagsparadoxon Auf Hashing angewendet bedeutet das: I Die Wahrscheinlichkeit keiner Kollision nach n zufälligen Einfügevorgängen in einer m-elementigen Tabelle ist: Y m−i m m−1 m − n + 1 n−1 · · ... · = m m m m i=0 Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 15/53 Hashing I Grundlagen des Hashings Kollisionen: Das Geburtstagsparadoxon Auf Hashing angewendet bedeutet das: I Die Wahrscheinlichkeit keiner Kollision nach n zufälligen Einfügevorgängen in einer m-elementigen Tabelle ist: Y m−i m m−1 m − n + 1 n−1 · · ... · = m m m m i=0 I Dieses Produkt geht mit wachsendem n (und m) gegen 0. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 15/53 Hashing I Grundlagen des Hashings Kollisionen: Das Geburtstagsparadoxon Auf Hashing angewendet bedeutet das: I Die Wahrscheinlichkeit keiner Kollision nach n zufälligen Einfügevorgängen in einer m-elementigen Tabelle ist: Y m−i m m−1 m − n + 1 n−1 · · ... · = m m m m i=0 I Dieses Produkt geht mit wachsendem n (und m) gegen 0. I Etwa bei m = 365 ist die Wahrscheinlichkeit für n > 50 praktisch 0. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 15/53 Hashing I Grundlagen des Hashings Kollisionen: Das Geburtstagsparadoxon Wahrscheinlichkeit keiner Kollision 1.0 0.8 0.6 0.4 0.2 20 40 60 80 100 Anzahl Einfügungen k Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 16/53 Hashing I Kollisionsauflösung durch Verkettung Übersicht 1 Direkte Adressierung 2 Grundlagen des Hashings 3 Kollisionsauflösung durch Verkettung 4 Hashfunktionen Divisionsmethode Multiplikationsmethode Universelles Hashing 5 Offene Adressierung Lineares Sondieren Quadratisches Sondieren Doppeltes Hashing Effizienz der offenen Adressierung Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 17/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Idee Alle Schlüssel, die zum gleichen Hash führen, werden in einer verketteten Liste gespeichert. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen [Luhn 1953] 18/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Idee Alle Schlüssel, die zum gleichen Hash führen, werden in einer verketteten Liste gespeichert. [Luhn 1953] 0 U K k2 k4 k1 k7 k3 k 6 k5 k1 k2 k3 k6 k7 k5 k4 m−1 Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 18/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Dictionary-Operationen bei Verkettung (informell) Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 19/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Dictionary-Operationen bei Verkettung (informell) I hcSearch(int k): Suche nach einem Element mit Schlüssel k in der Liste T[h(k)]. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 19/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Dictionary-Operationen bei Verkettung (informell) I hcSearch(int k): Suche nach einem Element mit Schlüssel k in der Liste T[h(k)]. I hcInsert(Element e): Setze Element e an den Anfang der Liste T[h(e.key)]. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 19/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Dictionary-Operationen bei Verkettung (informell) I hcSearch(int k): Suche nach einem Element mit Schlüssel k in der Liste T[h(k)]. I hcInsert(Element e): Setze Element e an den Anfang der Liste T[h(e.key)]. I hcDelete(Element e): Lösche Element e aus der Liste T[h(e.key)]. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 19/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Worst-Case Komplexität Angenommen, die Berechnung von h(k) ist recht effizient, etwa Θ(1). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 20/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Worst-Case Komplexität Angenommen, die Berechnung von h(k) ist recht effizient, etwa Θ(1). Die Komplexität ist: Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 20/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Worst-Case Komplexität Angenommen, die Berechnung von h(k) ist recht effizient, etwa Θ(1). Die Komplexität ist: Suche: Proportional zur Länge der Liste T [h(k)]. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 20/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Worst-Case Komplexität Angenommen, die Berechnung von h(k) ist recht effizient, etwa Θ(1). Die Komplexität ist: Suche: Proportional zur Länge der Liste T [h(k)]. Einfügen: Konstant (ohne Überprüfung, ob das Element schon vorhanden ist). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 20/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Worst-Case Komplexität Angenommen, die Berechnung von h(k) ist recht effizient, etwa Θ(1). Die Komplexität ist: Suche: Proportional zur Länge der Liste T [h(k)]. Einfügen: Konstant (ohne Überprüfung, ob das Element schon vorhanden ist). Löschen: Proportional zur Länge der Liste T [h(k)]. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 20/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Worst-Case Komplexität Angenommen, die Berechnung von h(k) ist recht effizient, etwa Θ(1). Die Komplexität ist: Suche: Proportional zur Länge der Liste T [h(k)]. Einfügen: Konstant (ohne Überprüfung, ob das Element schon vorhanden ist). Löschen: Proportional zur Länge der Liste T [h(k)]. I Im Worst-Case haben alle Schüssel den selben Hashwert. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 20/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Worst-Case Komplexität Angenommen, die Berechnung von h(k) ist recht effizient, etwa Θ(1). Die Komplexität ist: Suche: Proportional zur Länge der Liste T [h(k)]. Einfügen: Konstant (ohne Überprüfung, ob das Element schon vorhanden ist). Löschen: Proportional zur Länge der Liste T [h(k)]. I Im Worst-Case haben alle Schüssel den selben Hashwert. I Suche und Löschen hat dann die selbe Worst-Case Komplexität wie Listen: Θ(n). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 20/53 Hashing I Kollisionsauflösung durch Verkettung Kollisionsauflösung durch Verkettung Worst-Case Komplexität Angenommen, die Berechnung von h(k) ist recht effizient, etwa Θ(1). Die Komplexität ist: Suche: Proportional zur Länge der Liste T [h(k)]. Einfügen: Konstant (ohne Überprüfung, ob das Element schon vorhanden ist). Löschen: Proportional zur Länge der Liste T [h(k)]. I Im Worst-Case haben alle Schüssel den selben Hashwert. I Suche und Löschen hat dann die selbe Worst-Case Komplexität wie Listen: Θ(n). I Im Average-Case ist Hashing mit Verkettung aber dennoch effizient! Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 20/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Annahmen: I Gegeben seien n aus N möglichen Schlüsseln und m Hashtabellenpositionen, N m. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 21/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Annahmen: I Gegeben seien n aus N möglichen Schlüsseln und m Hashtabellenpositionen, N m. I Gleichverteiltes Hashing: Jeder Schlüssel wird mit gleicher Wahrscheinlichkeit und unabhängig von den anderen Schlüsseln auf jedes der m Slots abgebildet. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 21/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Annahmen: I Gegeben seien n aus N möglichen Schlüsseln und m Hashtabellenpositionen, N m. I Gleichverteiltes Hashing: Jeder Schlüssel wird mit gleicher Wahrscheinlichkeit und unabhängig von den anderen Schlüsseln auf jedes der m Slots abgebildet. I Der Hashwert h(k) kann in konstanter Zeit berechnet werden. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 21/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Annahmen: I Gegeben seien n aus N möglichen Schlüsseln und m Hashtabellenpositionen, N m. I Gleichverteiltes Hashing: Jeder Schlüssel wird mit gleicher Wahrscheinlichkeit und unabhängig von den anderen Schlüsseln auf jedes der m Slots abgebildet. I Der Hashwert h(k) kann in konstanter Zeit berechnet werden. O, Θ, Ω erweitert Aus technischen Gründen erweitern wir die Definition von O, Θ und Ω auf Funktionen mit zwei Parametern. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 21/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Annahmen: I Gegeben seien n aus N möglichen Schlüsseln und m Hashtabellenpositionen, N m. I Gleichverteiltes Hashing: Jeder Schlüssel wird mit gleicher Wahrscheinlichkeit und unabhängig von den anderen Schlüsseln auf jedes der m Slots abgebildet. I Der Hashwert h(k) kann in konstanter Zeit berechnet werden. O, Θ, Ω erweitert Aus technischen Gründen erweitern wir die Definition von O, Θ und Ω auf Funktionen mit zwei Parametern. I Beispielsweise ist g ∈ O(f ) gdw. ∃c > 0, n0 , m0 mit ∀n > n0 , m > m0 : 0 6 g(n, m) 6 c · f (n, m) Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 21/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung I Der Füllgrad der Hashtabelle T ist α(n, m) = Prof. Dr. Erika Ábrahám n m. Datenstrukturen und Algorithmen 22/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung I Der Füllgrad der Hashtabelle T ist α(n, m) = n m. ⇒ Auch die durchschnittliche Länge der Liste T[h(k)] ist α! Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 22/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung I Der Füllgrad der Hashtabelle T ist α(n, m) = n m. ⇒ Auch die durchschnittliche Länge der Liste T[h(k)] ist α! I Wieviele Elemente aus T[h(k)] müssen nun im Schnitt untersucht werden, um einen Schlüssel k zu finden? Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 22/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung I Der Füllgrad der Hashtabelle T ist α(n, m) = n m. ⇒ Auch die durchschnittliche Länge der Liste T[h(k)] ist α! I Wieviele Elemente aus T[h(k)] müssen nun im Schnitt untersucht werden, um einen Schlüssel k zu finden? ⇒ Unterscheide erfolgreiche von erfolgloser Suche (wie in Vorlesung 1). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 22/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolglose Suche Die erfolglose Suche benötigt Θ(1 + α) Zeit im Average-Case. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 23/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolglose Suche Die erfolglose Suche benötigt Θ(1 + α) Zeit im Average-Case. I Die erwartete Zeit, um Schlüssel k zu finden ist gerade die Zeit, um die Liste T[h(k)] zu durchsuchen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 23/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolglose Suche Die erfolglose Suche benötigt Θ(1 + α) Zeit im Average-Case. I Die erwartete Zeit, um Schlüssel k zu finden ist gerade die Zeit, um die Liste T[h(k)] zu durchsuchen. I Die erwartete Länge dieser Liste ist α. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 23/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolglose Suche Die erfolglose Suche benötigt Θ(1 + α) Zeit im Average-Case. I Die erwartete Zeit, um Schlüssel k zu finden ist gerade die Zeit, um die Liste T[h(k)] zu durchsuchen. I Die erwartete Länge dieser Liste ist α. I Das Berechnen von h(k) benötige nur eine Zeiteinheit. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 23/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolglose Suche Die erfolglose Suche benötigt Θ(1 + α) Zeit im Average-Case. I Die erwartete Zeit, um Schlüssel k zu finden ist gerade die Zeit, um die Liste T[h(k)] zu durchsuchen. I Die erwartete Länge dieser Liste ist α. I Das Berechnen von h(k) benötige nur eine Zeiteinheit. ⇒ Insgesamt erhält man 1 + α Zeiteinheiten im Durchschnitt. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 23/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolgreiche Suche Die erfolgreiche Suche benötigt im Average-Case auch Θ(1 + α). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 24/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolgreiche Suche Die erfolgreiche Suche benötigt im Average-Case auch Θ(1 + α). I Sei ki der i-te eingefügte Schlüssel und A(ki ) die erwartete Zeit, um ki zu finden: Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 24/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolgreiche Suche Die erfolgreiche Suche benötigt im Average-Case auch Θ(1 + α). I Sei ki der i-te eingefügte Schlüssel und A(ki ) die erwartete Zeit, um ki zu finden: A(ki ) = 1 + Prof. Dr. Erika Ábrahám Durchschnittliche Anzahl Schlüssel, die in T[h(k_i)] erst nach ki eingefügt wurden Datenstrukturen und Algorithmen 24/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolgreiche Suche Die erfolgreiche Suche benötigt im Average-Case auch Θ(1 + α). I Sei ki der i-te eingefügte Schlüssel und A(ki ) die erwartete Zeit, um ki zu finden: A(ki ) = 1 + I Durchschnittliche Anzahl Schlüssel, die in T[h(k_i)] erst nach ki eingefügt wurden Annahme von gleichverteiltem Hashing ergibt: A(ki ) = 1 + n X 1 j=i+1 Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen m 24/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Erfolgreiche Suche Die erfolgreiche Suche benötigt im Average-Case auch Θ(1 + α). I Sei ki der i-te eingefügte Schlüssel und A(ki ) die erwartete Zeit, um ki zu finden: A(ki ) = 1 + I I Durchschnittliche Anzahl Schlüssel, die in T[h(k_i)] erst nach ki eingefügt wurden Annahme von gleichverteiltem Hashing ergibt: A(ki ) = 1 + Durchschnitt über alle n Einfügungen in die Hashtabelle: Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 1 n n X 1 j=i+1 n X m A(ki ) i=1 24/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Die erwartete Anzahl an untersuchten Elementen bei einer erfolgreichen Suche ist: Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 25/53 Hashing I Kollisionsauflösung durch Verkettung Average-Case-Analyse von Verkettung Die erwartete Anzahl an untersuchten Elementen bei einer erfolgreichen Suche ist: n 1X n 1 + i=1 n X 1 m j=i+1 Summe aufteilen n n X n 1X 1 X = 1+ 1 n i=1 nm i=1 j=i+1 Vereinfachen n 1 X =1+ (n − i) nm i=1 Summe 1 . . . n − 1 1 n(n − 1) · nm 2 n−1 α α =1+ =1+ − 2m 2 2n =1+ Prof. Dr. Erika Ábrahám Vereinfachen und damit in Θ(1 + α) Datenstrukturen und Algorithmen 25/53 Hashing I Kollisionsauflösung durch Verkettung Komplexität der Dictionary-Operationen mit Verkettung I Vorausgesetzt die Tabellengröße m ist (wenigstens) proportional zu N, Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 26/53 Hashing I Kollisionsauflösung durch Verkettung Komplexität der Dictionary-Operationen mit Verkettung I Vorausgesetzt die Tabellengröße m ist (wenigstens) proportional zu N, I dann ist der Füllgrad α(n, m) = Prof. Dr. Erika Ábrahám n m ∈ O(m) m = O(1). Datenstrukturen und Algorithmen 26/53 Hashing I Kollisionsauflösung durch Verkettung Komplexität der Dictionary-Operationen mit Verkettung I Vorausgesetzt die Tabellengröße m ist (wenigstens) proportional zu N, I dann ist der Füllgrad α(n, m) = I Damit benötigen alle Operationen im Durchschnitt O(1). Prof. Dr. Erika Ábrahám n m ∈ O(m) m = O(1). Datenstrukturen und Algorithmen 26/53 Hashing I Kollisionsauflösung durch Verkettung Komplexität der Dictionary-Operationen mit Verkettung I Vorausgesetzt die Tabellengröße m ist (wenigstens) proportional zu N, I dann ist der Füllgrad α(n, m) = I Damit benötigen alle Operationen im Durchschnitt O(1). I Weil das auch Suche mit einschließt, können wir im Average-Case mit O(n) sortieren. Prof. Dr. Erika Ábrahám n m ∈ O(m) m = O(1). Datenstrukturen und Algorithmen 26/53 Hashing I Hashfunktionen Übersicht 1 Direkte Adressierung 2 Grundlagen des Hashings 3 Kollisionsauflösung durch Verkettung 4 Hashfunktionen Divisionsmethode Multiplikationsmethode Universelles Hashing 5 Offene Adressierung Lineares Sondieren Quadratisches Sondieren Doppeltes Hashing Effizienz der offenen Adressierung Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 27/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. I Wir interpretieren Schlüssel als natürliche Zahlen (Beispiel: Strings auf N abbilden). Was macht eine „gute“ Hashfunktion aus? I Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. I Wir interpretieren Schlüssel als natürliche Zahlen (Beispiel: Strings auf N abbilden). Was macht eine „gute“ Hashfunktion aus? I I Die Hashfunktion h(k) sollte einfach zu berechnen sein, Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. I Wir interpretieren Schlüssel als natürliche Zahlen (Beispiel: Strings auf N abbilden). Was macht eine „gute“ Hashfunktion aus? I I I Die Hashfunktion h(k) sollte einfach zu berechnen sein, sie sollte surjektiv auf der Menge 0 . . . m−1 sein, Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. I Wir interpretieren Schlüssel als natürliche Zahlen (Beispiel: Strings auf N abbilden). Was macht eine „gute“ Hashfunktion aus? I I I I Die Hashfunktion h(k) sollte einfach zu berechnen sein, sie sollte surjektiv auf der Menge 0 . . . m−1 sein, sie sollte alle Indizes mit möglichst gleicher Häufigkeit verwenden (unabhängig von Mustern in der Schlüsselverteilung sein), und Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. I Wir interpretieren Schlüssel als natürliche Zahlen (Beispiel: Strings auf N abbilden). Was macht eine „gute“ Hashfunktion aus? I I I I I Die Hashfunktion h(k) sollte einfach zu berechnen sein, sie sollte surjektiv auf der Menge 0 . . . m−1 sein, sie sollte alle Indizes mit möglichst gleicher Häufigkeit verwenden (unabhängig von Mustern in der Schlüsselverteilung sein), und ähnliche Schlüssel möglichst breit auf die Hashtabelle verteilen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. I Wir interpretieren Schlüssel als natürliche Zahlen (Beispiel: Strings auf N abbilden). Was macht eine „gute“ Hashfunktion aus? I I I I I I Die Hashfunktion h(k) sollte einfach zu berechnen sein, sie sollte surjektiv auf der Menge 0 . . . m−1 sein, sie sollte alle Indizes mit möglichst gleicher Häufigkeit verwenden (unabhängig von Mustern in der Schlüsselverteilung sein), und ähnliche Schlüssel möglichst breit auf die Hashtabelle verteilen. Drei oft verwendete Techniken, eine „gute“ Hashfunktion zu erhalten: Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. I Wir interpretieren Schlüssel als natürliche Zahlen (Beispiel: Strings auf N abbilden). Was macht eine „gute“ Hashfunktion aus? I I I I I I Die Hashfunktion h(k) sollte einfach zu berechnen sein, sie sollte surjektiv auf der Menge 0 . . . m−1 sein, sie sollte alle Indizes mit möglichst gleicher Häufigkeit verwenden (unabhängig von Mustern in der Schlüsselverteilung sein), und ähnliche Schlüssel möglichst breit auf die Hashtabelle verteilen. Drei oft verwendete Techniken, eine „gute“ Hashfunktion zu erhalten: I Die Divisionsmethode, Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. I Wir interpretieren Schlüssel als natürliche Zahlen (Beispiel: Strings auf N abbilden). Was macht eine „gute“ Hashfunktion aus? I I I I I I Die Hashfunktion h(k) sollte einfach zu berechnen sein, sie sollte surjektiv auf der Menge 0 . . . m−1 sein, sie sollte alle Indizes mit möglichst gleicher Häufigkeit verwenden (unabhängig von Mustern in der Schlüsselverteilung sein), und ähnliche Schlüssel möglichst breit auf die Hashtabelle verteilen. Drei oft verwendete Techniken, eine „gute“ Hashfunktion zu erhalten: I I Die Divisionsmethode, die Multiplikationsmethode, und Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Hashfunktionen Hashfunktion I Eine Hashfunktion bildet Schlüssel auf ganze Zahlen (d. h. Indices) ab. I Wir interpretieren Schlüssel als natürliche Zahlen (Beispiel: Strings auf N abbilden). Was macht eine „gute“ Hashfunktion aus? I I I I I I Die Hashfunktion h(k) sollte einfach zu berechnen sein, sie sollte surjektiv auf der Menge 0 . . . m−1 sein, sie sollte alle Indizes mit möglichst gleicher Häufigkeit verwenden (unabhängig von Mustern in der Schlüsselverteilung sein), und ähnliche Schlüssel möglichst breit auf die Hashtabelle verteilen. Drei oft verwendete Techniken, eine „gute“ Hashfunktion zu erhalten: I I I Die Divisionsmethode, die Multiplikationsmethode, und universelles Hashing. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 28/53 Hashing I Hashfunktionen Divisionsmethode Divisionsmethode Hashfunktion: h(k) = k mod m Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 29/53 Hashing I Hashfunktionen Divisionsmethode Divisionsmethode Hashfunktion: h(k) = k mod m I Bei dieser Methode muss der Wert von m sorgfältig gewählt werden. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 29/53 Hashing I Hashfunktionen Divisionsmethode Divisionsmethode Hashfunktion: h(k) = k mod m I Bei dieser Methode muss der Wert von m sorgfältig gewählt werden. I Für m = 2p ist h(k) einfach die letzten p Bits. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 29/53 Hashing I Hashfunktionen Divisionsmethode Divisionsmethode Hashfunktion: h(k) = k mod m I Bei dieser Methode muss der Wert von m sorgfältig gewählt werden. I I Für m = 2p ist h(k) einfach die letzten p Bits. Besser ist es, h(k) abhängig von den Bits der Schlüsseln zu machen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 29/53 Hashing I Hashfunktionen Divisionsmethode Divisionsmethode Hashfunktion: h(k) = k mod m I Bei dieser Methode muss der Wert von m sorgfältig gewählt werden. I I I Für m = 2p ist h(k) einfach die letzten p Bits. Besser ist es, h(k) abhängig von den Bits der Schlüsseln zu machen. Gute Wahl ist m prim und nicht zu nah an einer Zweierpotenz. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 29/53 Hashing I Hashfunktionen Divisionsmethode Divisionsmethode Hashfunktion: h(k) = k mod m I Bei dieser Methode muss der Wert von m sorgfältig gewählt werden. I I I Für m = 2p ist h(k) einfach die letzten p Bits. Besser ist es, h(k) abhängig von den Bits der Schlüsseln zu machen. Gute Wahl ist m prim und nicht zu nah an einer Zweierpotenz. Beispiel I Strings mit 2000 Zeichen als Schlüssel. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 29/53 Hashing I Hashfunktionen Divisionsmethode Divisionsmethode Hashfunktion: h(k) = k mod m I Bei dieser Methode muss der Wert von m sorgfältig gewählt werden. I I I Für m = 2p ist h(k) einfach die letzten p Bits. Besser ist es, h(k) abhängig von den Bits der Schlüsseln zu machen. Gute Wahl ist m prim und nicht zu nah an einer Zweierpotenz. Beispiel I Strings mit 2000 Zeichen als Schlüssel. I Wir erlauben durchschnittlich 3 Schlüsseln pro Tabellenplatz. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 29/53 Hashing I Hashfunktionen Divisionsmethode Divisionsmethode Hashfunktion: h(k) = k mod m I Bei dieser Methode muss der Wert von m sorgfältig gewählt werden. I I I Für m = 2p ist h(k) einfach die letzten p Bits. Besser ist es, h(k) abhängig von den Bits der Schlüsseln zu machen. Gute Wahl ist m prim und nicht zu nah an einer Zweierpotenz. Beispiel I Strings mit 2000 Zeichen als Schlüssel. Wir erlauben durchschnittlich 3 Schlüsseln pro Tabellenplatz. ⇒ Wähle m ≈ 2000/3 −→ 701. I I I I Nahe an 2000/3 Primzahl Nicht in der Nähe von 2er-Potenzen Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 29/53 Hashing I Hashfunktionen Multiplikationsmethode Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c für 0 < c < 1 Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 30/53 Hashing I Hashfunktionen Multiplikationsmethode Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c für 0 < c < 1 I k·c mod 1 ist der Nachkommateil von k·c, d. h. k·c − bk·cc. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 30/53 Hashing I Hashfunktionen Multiplikationsmethode Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c für 0 < c < 1 I I k·c mod 1 ist der Nachkommateil von k·c, d. h. k·c − bk·cc. √ Knuth empfiehlt c ≈ ( 5 − 1)/2 ≈ 0,62. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 30/53 Hashing I Hashfunktionen Multiplikationsmethode Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c für 0 < c < 1 I I k·c mod 1 ist der Nachkommateil von k·c, d. h. k·c − bk·cc. √ Knuth empfiehlt c ≈ ( 5 − 1)/2 ≈ 0,62. ⇒ Der Wert von m ist hier nicht kritisch. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 30/53 Hashing I Hashfunktionen Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 31/53 Hashing I Hashfunktionen Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c. I Das übliche Vorgehen nimmt für w -Bit-Schlüsseln m = 2p und c = 2sw , wobei 0 < s < 2w . Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 31/53 Hashing I Hashfunktionen Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c. I Das übliche Vorgehen nimmt für w -Bit-Schlüsseln m = 2p und c = 2sw , wobei 0 < s < 2w . Dann ist die Implementierung einfach: I Berechne zunächst k·s (= k·c·2w ). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 31/53 Hashing I Hashfunktionen Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c. I Das übliche Vorgehen nimmt für w -Bit-Schlüsseln m = 2p und c = 2sw , wobei 0 < s < 2w . Dann ist die Implementierung einfach: I I Berechne zunächst k·s (= k·c·2w ). Teile durch 2w , verwende nur die Nachkommastellen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 31/53 Hashing I Hashfunktionen Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c. I Das übliche Vorgehen nimmt für w -Bit-Schlüsseln m = 2p und c = 2sw , wobei 0 < s < 2w . Dann ist die Implementierung einfach: I I I Berechne zunächst k·s (= k·c·2w ). Teile durch 2w , verwende nur die Nachkommastellen. Multipliziere mit 2p und verwende nur den ganzzahligen Anteil. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 31/53 Hashing I Hashfunktionen Multiplikationsmethode Hashfunktion: h(k) = bm·(k·c mod 1)c. I Das übliche Vorgehen nimmt für w -Bit-Schlüsseln m = 2p und c = 2sw , wobei 0 < s < 2w . Dann ist die Implementierung einfach: I I I Berechne zunächst k·s (= k·c·2w ). Teile durch 2w , verwende nur die Nachkommastellen. Multipliziere mit 2p und verwende nur den ganzzahligen Anteil. w Bits Schlüssel k ∗ c · 2w p Bits extrahieren h(k) Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 31/53 Hashing I Hashfunktionen Universelles Hashing Das größte Problem beim Hashing ist, I dass es immer eine ungünstige Sequenz von Schlüsseln gibt, die auf den selben Slot abgebildet werden. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 32/53 Hashing I Hashfunktionen Universelles Hashing Das größte Problem beim Hashing ist, I dass es immer eine ungünstige Sequenz von Schlüsseln gibt, die auf den selben Slot abgebildet werden. Idee Wähle zufällig eine Hashfunktion aus einer gegebenen kleinen Menge H, unabhängig von den verwendeten Schlüsseln. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 32/53 Hashing I Hashfunktionen Universelles Hashing Das größte Problem beim Hashing ist, I dass es immer eine ungünstige Sequenz von Schlüsseln gibt, die auf den selben Slot abgebildet werden. Idee Wähle zufällig eine Hashfunktion aus einer gegebenen kleinen Menge H, unabhängig von den verwendeten Schlüsseln. Eine Menge Hashfunktionen ist universell, wenn I der Anteil der Funktionen aus H, so dass k und k 0 kollidieren ist Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen |H| m . 32/53 Hashing I Hashfunktionen Universelles Hashing Das größte Problem beim Hashing ist, I dass es immer eine ungünstige Sequenz von Schlüsseln gibt, die auf den selben Slot abgebildet werden. Idee Wähle zufällig eine Hashfunktion aus einer gegebenen kleinen Menge H, unabhängig von den verwendeten Schlüsseln. Eine Menge Hashfunktionen ist universell, wenn I der Anteil der Funktionen aus H, so dass k und k 0 kollidieren ist I d. h., die W’lichkeit einer Kollision von k und k 0 ist 1 |H| · |H| m = |H| m . 1 m. Für universelles Hashing ist die erwartete Länge der Liste T[k] Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 32/53 Hashing I Hashfunktionen Universelles Hashing Das größte Problem beim Hashing ist, I dass es immer eine ungünstige Sequenz von Schlüsseln gibt, die auf den selben Slot abgebildet werden. Idee Wähle zufällig eine Hashfunktion aus einer gegebenen kleinen Menge H, unabhängig von den verwendeten Schlüsseln. Eine Menge Hashfunktionen ist universell, wenn I der Anteil der Funktionen aus H, so dass k und k 0 kollidieren ist I d. h., die W’lichkeit einer Kollision von k und k 0 ist 1 |H| · |H| m = |H| m . 1 m. Für universelles Hashing ist die erwartete Länge der Liste T[k] 1. Gleich α, wenn k nicht in T enthalten ist. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 32/53 Hashing I Hashfunktionen Universelles Hashing Das größte Problem beim Hashing ist, I dass es immer eine ungünstige Sequenz von Schlüsseln gibt, die auf den selben Slot abgebildet werden. Idee Wähle zufällig eine Hashfunktion aus einer gegebenen kleinen Menge H, unabhängig von den verwendeten Schlüsseln. Eine Menge Hashfunktionen ist universell, wenn I der Anteil der Funktionen aus H, so dass k und k 0 kollidieren ist I d. h., die W’lichkeit einer Kollision von k und k 0 ist 1 |H| · |H| m = |H| m . 1 m. Für universelles Hashing ist die erwartete Länge der Liste T[k] 1. Gleich α, wenn k nicht in T enthalten ist. 2. Gleich 1+α, wenn k in T enthalten ist. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 32/53 Hashing I Hashfunktionen Universelles Hashing Beispiel Definiere die Elemente der Klasse H von Hashfunktionen durch: ha,b (k) = ((a · k + b) mod p) mod m I p sei Primzahl mit p > m und p > größter Schlüssel. I Die ganzen Zahlen a (1 6 a < p) und b (0 6 b < p) werden erst bei der Ausführung gewählt. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 33/53 Hashing I Hashfunktionen Universelles Hashing Beispiel Definiere die Elemente der Klasse H von Hashfunktionen durch: ha,b (k) = ((a · k + b) mod p) mod m I p sei Primzahl mit p > m und p > größter Schlüssel. I Die ganzen Zahlen a (1 6 a < p) und b (0 6 b < p) werden erst bei der Ausführung gewählt. Die Klasse der obigen Hashfunktionen ha,b ist universell. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 33/53 Hashing I Offene Adressierung Übersicht 1 Direkte Adressierung 2 Grundlagen des Hashings 3 Kollisionsauflösung durch Verkettung 4 Hashfunktionen Divisionsmethode Multiplikationsmethode Universelles Hashing 5 Offene Adressierung Lineares Sondieren Quadratisches Sondieren Doppeltes Hashing Effizienz der offenen Adressierung Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 34/53 Hashing I Offene Adressierung Offene Adressierung I Alle Elemente werden direkt in der Hashtabelle gespeichert (im Gegensatz zur Verkettung). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 35/53 Hashing I Offene Adressierung Offene Adressierung I Alle Elemente werden direkt in der Hashtabelle gespeichert (im Gegensatz zur Verkettung). ⇒ Höchstens m Schlüssel können gespeichert werden, d. h. n 6 1. α(n, m) = m I Man spart aber den Platz für die Pointer. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 35/53 Hashing I Offene Adressierung Offene Adressierung I Alle Elemente werden direkt in der Hashtabelle gespeichert (im Gegensatz zur Verkettung). ⇒ Höchstens m Schlüssel können gespeichert werden, d. h. n 6 1. α(n, m) = m I Man spart aber den Platz für die Pointer. Einfügen von Schlüssel k I Sondiere (überprüfe) die Positionen der Hashtabelle in einer bestimmten Reihenfolge, bis ein leerer Slot gefunden wurde. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 35/53 Hashing I Offene Adressierung Offene Adressierung I Alle Elemente werden direkt in der Hashtabelle gespeichert (im Gegensatz zur Verkettung). ⇒ Höchstens m Schlüssel können gespeichert werden, d. h. n 6 1. α(n, m) = m I Man spart aber den Platz für die Pointer. Einfügen von Schlüssel k I Sondiere (überprüfe) die Positionen der Hashtabelle in einer bestimmten Reihenfolge, bis ein leerer Slot gefunden wurde. I Die Reihenfolge der Positionen sind vom einzufügenden Schlüssel k abgeleitet. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 35/53 Hashing I Offene Adressierung Offene Adressierung I Alle Elemente werden direkt in der Hashtabelle gespeichert (im Gegensatz zur Verkettung). ⇒ Höchstens m Schlüssel können gespeichert werden, d. h. n 6 1. α(n, m) = m I Man spart aber den Platz für die Pointer. Einfügen von Schlüssel k I Sondiere (überprüfe) die Positionen der Hashtabelle in einer bestimmten Reihenfolge, bis ein leerer Slot gefunden wurde. I Die Reihenfolge der Positionen sind vom einzufügenden Schlüssel k abgeleitet. I Die Hashfunktion hängt also vom Schlüssel k und der Nummer der Sondierung ab: h : U × { 0, 1, . . . m − 1 } −→ { 0, 1, . . . m − 1 } Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 35/53 Hashing I Offene Adressierung Einfügen bei offener Adressierung 1 2 3 4 5 6 7 8 9 10 void hashInsert(int T[], int key) { for (int i = 0; i < T.length; i++) { // Teste ganze Tabelle int pos = h(key, i); // Berechne i-te Sondierung if (!T[pos]) { // freier Platz T[pos] = key; return; // fertig } } throw "Überlauf der Hashtabelle"; } Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 36/53 Hashing I Offene Adressierung Suche bei offener Adressierung 1 2 3 4 5 6 7 8 9 10 11 int hashSearch(int T[], int key) { for (int i = 0; i < T.length; i++) { int pos = h(key, i); // Berechne i-te Sondierung if (T[pos] == key) { // Schlüssel k gefunden return T[pos]; } else if (!T[pos]) { // freier Platz, nicht gefunden break; } } return -1; // "nicht gefunden" } Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 37/53 Hashing I Offene Adressierung Löschen bei offener Adressierung Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 38/53 Hashing I Offene Adressierung Löschen bei offener Adressierung Problem Löschen des Schlüssels k aus Slot i durch T[i] = null ist ungeeignet: Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 38/53 Hashing I Offene Adressierung Löschen bei offener Adressierung Problem Löschen des Schlüssels k aus Slot i durch T[i] = null ist ungeeignet: I Wenn beim Einfügen von k der Slot i besetzt war, können wir k nicht mehr abrufen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 38/53 Hashing I Offene Adressierung Löschen bei offener Adressierung Problem Löschen des Schlüssels k aus Slot i durch T[i] = null ist ungeeignet: I Wenn beim Einfügen von k der Slot i besetzt war, können wir k nicht mehr abrufen. Lösung Markiere T[i] mit dem speziellen Wert DELETED (oder: „veraltet“). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 38/53 Hashing I Offene Adressierung Löschen bei offener Adressierung Problem Löschen des Schlüssels k aus Slot i durch T[i] = null ist ungeeignet: I Wenn beim Einfügen von k der Slot i besetzt war, können wir k nicht mehr abrufen. Lösung Markiere T[i] mit dem speziellen Wert DELETED (oder: „veraltet“). I hashInsert muss angepasst werden und solche Slots als leer betrachten. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 38/53 Hashing I Offene Adressierung Löschen bei offener Adressierung Problem Löschen des Schlüssels k aus Slot i durch T[i] = null ist ungeeignet: I Wenn beim Einfügen von k der Slot i besetzt war, können wir k nicht mehr abrufen. Lösung Markiere T[i] mit dem speziellen Wert DELETED (oder: „veraltet“). I hashInsert muss angepasst werden und solche Slots als leer betrachten. I hashSearch bleibt unverändert, solche Slots werden einfach übergangen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 38/53 Hashing I Offene Adressierung Löschen bei offener Adressierung Problem Löschen des Schlüssels k aus Slot i durch T[i] = null ist ungeeignet: I Wenn beim Einfügen von k der Slot i besetzt war, können wir k nicht mehr abrufen. Lösung Markiere T[i] mit dem speziellen Wert DELETED (oder: „veraltet“). I hashInsert muss angepasst werden und solche Slots als leer betrachten. I hashSearch bleibt unverändert, solche Slots werden einfach übergangen. I Die Suchzeiten sind nun nicht mehr allein vom Füllgrad α abhängig. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 38/53 Hashing I Offene Adressierung Löschen bei offener Adressierung Problem Löschen des Schlüssels k aus Slot i durch T[i] = null ist ungeeignet: I Wenn beim Einfügen von k der Slot i besetzt war, können wir k nicht mehr abrufen. Lösung Markiere T[i] mit dem speziellen Wert DELETED (oder: „veraltet“). I hashInsert muss angepasst werden und solche Slots als leer betrachten. I hashSearch bleibt unverändert, solche Slots werden einfach übergangen. Die Suchzeiten sind nun nicht mehr allein vom Füllgrad α abhängig. ⇒ Wenn Schlüssel gelöscht werden sollen wird häufiger Verkettung verwendet. I Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 38/53 Hashing I Offene Adressierung Wie wählt man die nächste Sondierung? Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 39/53 Hashing I Offene Adressierung Wie wählt man die nächste Sondierung? Wir benötigen eine Sondierungssequenz für einen gegebenen Schlüssel k: hh(k, 0), h(k, 1), . . . , h(k, m−1)i Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 39/53 Hashing I Offene Adressierung Wie wählt man die nächste Sondierung? Wir benötigen eine Sondierungssequenz für einen gegebenen Schlüssel k: hh(k, 0), h(k, 1), . . . , h(k, m−1)i I Wenn es sich dabei um eine Permutation von h0, . . . m − 1i handelt ist garantiert, dass jeder Slot letztlich geprüft wird. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 39/53 Hashing I Offene Adressierung Wie wählt man die nächste Sondierung? Wir benötigen eine Sondierungssequenz für einen gegebenen Schlüssel k: hh(k, 0), h(k, 1), . . . , h(k, m−1)i I Wenn es sich dabei um eine Permutation von h0, . . . m − 1i handelt ist garantiert, dass jeder Slot letztlich geprüft wird. I Gleichverteiltes Hashing wäre ideal, d. h. jede der m! Permutationen ist als Sondierungssequenz gleich wahrscheinlich. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 39/53 Hashing I Offene Adressierung Wie wählt man die nächste Sondierung? Wir benötigen eine Sondierungssequenz für einen gegebenen Schlüssel k: hh(k, 0), h(k, 1), . . . , h(k, m−1)i I Wenn es sich dabei um eine Permutation von h0, . . . m − 1i handelt ist garantiert, dass jeder Slot letztlich geprüft wird. I Gleichverteiltes Hashing wäre ideal, d. h. jede der m! Permutationen ist als Sondierungssequenz gleich wahrscheinlich. I In der Praxis ist das aber zu aufwändig und wird approximiert. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 39/53 Hashing I Offene Adressierung Wie wählt man die nächste Sondierung? Wir benötigen eine Sondierungssequenz für einen gegebenen Schlüssel k: hh(k, 0), h(k, 1), . . . , h(k, m−1)i I Wenn es sich dabei um eine Permutation von h0, . . . m − 1i handelt ist garantiert, dass jeder Slot letztlich geprüft wird. I Gleichverteiltes Hashing wäre ideal, d. h. jede der m! Permutationen ist als Sondierungssequenz gleich wahrscheinlich. I In der Praxis ist das aber zu aufwändig und wird approximiert. Sondierungsverfahren Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 39/53 Hashing I Offene Adressierung Wie wählt man die nächste Sondierung? Wir benötigen eine Sondierungssequenz für einen gegebenen Schlüssel k: hh(k, 0), h(k, 1), . . . , h(k, m−1)i I Wenn es sich dabei um eine Permutation von h0, . . . m − 1i handelt ist garantiert, dass jeder Slot letztlich geprüft wird. I Gleichverteiltes Hashing wäre ideal, d. h. jede der m! Permutationen ist als Sondierungssequenz gleich wahrscheinlich. I In der Praxis ist das aber zu aufwändig und wird approximiert. Sondierungsverfahren I Wir behandeln Lineares Sondieren, Quadratisches Sondieren und Doppeltes Hashing. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 39/53 Hashing I Offene Adressierung Wie wählt man die nächste Sondierung? Wir benötigen eine Sondierungssequenz für einen gegebenen Schlüssel k: hh(k, 0), h(k, 1), . . . , h(k, m−1)i I Wenn es sich dabei um eine Permutation von h0, . . . m − 1i handelt ist garantiert, dass jeder Slot letztlich geprüft wird. I Gleichverteiltes Hashing wäre ideal, d. h. jede der m! Permutationen ist als Sondierungssequenz gleich wahrscheinlich. I In der Praxis ist das aber zu aufwändig und wird approximiert. Sondierungsverfahren I Wir behandeln Lineares Sondieren, Quadratisches Sondieren und Doppeltes Hashing. I Die Qualität ist durch die Anzahl der verschiedenen Sondierungssequenzen, die jeweils erzeugt werden, bestimmt. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 39/53 Hashing I Offene Adressierung Lineares Sondieren Hashfunktion beim linearen Sondieren h(k, i) = (h0 (k) + i) mod m (für i < m). I k ist der Schlüssel I i ist der Index im Sondierungssequenz I h0 ist eine übliche Hashfunktion. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 40/53 Hashing I Offene Adressierung Lineares Sondieren: Beispiel 22 0 1 2 3 4 4 ins(17) 15 5 1. Son28 6 dierung 7 8 31 9 10 10 22 0 1 2 3 4 4 ins(17) 15 5 2. Son28 6 dierung 7 8 31 9 10 10 h0 (k) = k mod 11 Prof. Dr. Erika Ábrahám 22 0 1 2 3 4 4 15 5 28 6 17 7 8 31 9 10 10 h(k, i) = (h0 (k) + i) mod 11 Datenstrukturen und Algorithmen 41/53 Hashing I Offene Adressierung Lineares Sondieren: Beispiel 22 0 1 2 3 4 4 ins(17) 15 5 1. Son28 6 dierung 7 8 31 9 10 10 22 0 1 2 3 4 4 ins(17) 15 5 2. Son28 6 dierung 7 8 31 9 10 10 h0 (k) = k mod 11 Prof. Dr. Erika Ábrahám 22 0 1 2 3 4 4 ins(59) 15 5 1. Son28 6 dierung 17 7 8 31 9 10 10 22 0 1 2 3 4 4 ins(59) 15 5 2. Son28 6 dierung 17 7 8 31 9 10 10 22 0 1 2 3 4 4 ins(59) 15 5 3. Son28 6 dierung 17 7 8 31 9 10 10 h(k, i) = (h0 (k) + i) mod 11 Datenstrukturen und Algorithmen 41/53 Hashing I Offene Adressierung Lineares Sondieren Hashfunktion beim linearen Sondieren h(k, i) = (h0 (k) + i) mod m (für i < m). I h0 ist eine übliche Hashfunktion. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 42/53 Hashing I Offene Adressierung Lineares Sondieren Hashfunktion beim linearen Sondieren h(k, i) = (h0 (k) + i) mod m (für i < m). I h0 ist eine übliche Hashfunktion. I Die Verschiebung der nachfolgende Sondierungen ist linear von i abhängig. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 42/53 Hashing I Offene Adressierung Lineares Sondieren Hashfunktion beim linearen Sondieren h(k, i) = (h0 (k) + i) mod m (für i < m). I h0 ist eine übliche Hashfunktion. I Die Verschiebung der nachfolgende Sondierungen ist linear von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 42/53 Hashing I Offene Adressierung Lineares Sondieren Hashfunktion beim linearen Sondieren h(k, i) = (h0 (k) + i) mod m (für i < m). I h0 ist eine übliche Hashfunktion. I Die Verschiebung der nachfolgende Sondierungen ist linear von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. ⇒ m verschiedene Sequenzen können erzeugt werden. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 42/53 Hashing I Offene Adressierung Lineares Sondieren Hashfunktion beim linearen Sondieren h(k, i) = (h0 (k) + i) mod m (für i < m). I h0 ist eine übliche Hashfunktion. I Die Verschiebung der nachfolgende Sondierungen ist linear von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. ⇒ m verschiedene Sequenzen können erzeugt werden. I Clustering, also lange Folgen von belegten Slots, führt zu Problemen: Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 42/53 Hashing I Offene Adressierung Lineares Sondieren Hashfunktion beim linearen Sondieren h(k, i) = (h0 (k) + i) mod m (für i < m). I h0 ist eine übliche Hashfunktion. I Die Verschiebung der nachfolgende Sondierungen ist linear von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. ⇒ m verschiedene Sequenzen können erzeugt werden. I Clustering, also lange Folgen von belegten Slots, führt zu Problemen: I h0 (k) bleibt konstant, aber der Offset wird jedes Mal um eins größer. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 42/53 Hashing I Offene Adressierung Lineares Sondieren Hashfunktion beim linearen Sondieren h(k, i) = (h0 (k) + i) mod m (für i < m). I h0 ist eine übliche Hashfunktion. I Die Verschiebung der nachfolgende Sondierungen ist linear von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. ⇒ m verschiedene Sequenzen können erzeugt werden. I Clustering, also lange Folgen von belegten Slots, führt zu Problemen: I I h0 (k) bleibt konstant, aber der Offset wird jedes Mal um eins größer. Ein leerer Slot, dem i volle Slots vorausgehen, wird als nächstes mit Wahrscheinlichkeit i+1 m gefüllt. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 42/53 Hashing I Offene Adressierung Lineares Sondieren Hashfunktion beim linearen Sondieren h(k, i) = (h0 (k) + i) mod m (für i < m). I h0 ist eine übliche Hashfunktion. I Die Verschiebung der nachfolgende Sondierungen ist linear von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. ⇒ m verschiedene Sequenzen können erzeugt werden. I Clustering, also lange Folgen von belegten Slots, führt zu Problemen: h0 (k) bleibt konstant, aber der Offset wird jedes Mal um eins größer. I Ein leerer Slot, dem i volle Slots vorausgehen, wird als nächstes mit Wahrscheinlichkeit i+1 m gefüllt. ⇒ Lange Folgen tendieren dazu länger zu werden. I Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 42/53 Hashing I Offene Adressierung Quadratisches Sondieren Hashfunktion beim quadratischen Sondieren h(k, i) = (h0 (k) + c1 · i + c2 · i 2 ) mod m (für i < m). I k ist der Schlüssel I i ist der Index im Sondierungssequenz I h0 ist eine übliche Hashfunktion, und I c1 ∈ N, c2 ∈ N \ {0} geeignete Konstanten. Eine geeignete Wahl für die Konstanten c1 und c2 in Abhängigkeit von m: m = 2n , c1 = 12 , c2 = 12 Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 43/53 Hashing I Offene Adressierung Quadratisches Sondieren: Beispiel 22 0 1 2 3 4 4 ins(17) 5 1. Son28 6 dierung 7 15 8 31 9 10 10 22 0 1 2 3 4 4 ins(17) 5 2. Son28 6 dierung 7 15 8 31 9 10 10 h0 (k) = k mod 11 Prof. Dr. Erika Ábrahám 22 0 1 2 3 4 4 ins(17) 5 3. Son28 6 dierung 7 15 8 31 9 10 10 22 0 1 2 3 4 4 ins(17) 5 4. Son28 6 dierung 7 15 8 31 9 10 10 22 0 1 2 17 3 4 4 5 28 6 7 15 8 31 9 10 10 h(k, i) = (h0 (k) + i + 3i 2 ) mod 11 Datenstrukturen und Algorithmen 44/53 Hashing I Offene Adressierung Quadratisches Sondieren Hashfunktion beim quadratischen Sondieren h(k, i) = (h0 (k) + c1 · i + c2 · i 2 ) mod m (für i < m). I h0 ist eine übliche Hashfunktion, c1 , c2 6= 0 Konstanten. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 45/53 Hashing I Offene Adressierung Quadratisches Sondieren Hashfunktion beim quadratischen Sondieren h(k, i) = (h0 (k) + c1 · i + c2 · i 2 ) mod m (für i < m). I h0 ist eine übliche Hashfunktion, c1 , c2 6= 0 Konstanten. I Die Verschiebung der nachfolgende Sondierungen ist quadratisch von i abhängig. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 45/53 Hashing I Offene Adressierung Quadratisches Sondieren Hashfunktion beim quadratischen Sondieren h(k, i) = (h0 (k) + c1 · i + c2 · i 2 ) mod m (für i < m). I h0 ist eine übliche Hashfunktion, c1 , c2 6= 0 Konstanten. I Die Verschiebung der nachfolgende Sondierungen ist quadratisch von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 45/53 Hashing I Offene Adressierung Quadratisches Sondieren Hashfunktion beim quadratischen Sondieren h(k, i) = (h0 (k) + c1 · i + c2 · i 2 ) mod m (für i < m). I h0 ist eine übliche Hashfunktion, c1 , c2 6= 0 Konstanten. I Die Verschiebung der nachfolgende Sondierungen ist quadratisch von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. ⇒ Auch hier können m verschiedene Sequenzen erzeugt werden (wenn c1 , c2 geeignet gewählt wurden). Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 45/53 Hashing I Offene Adressierung Quadratisches Sondieren Hashfunktion beim quadratischen Sondieren h(k, i) = (h0 (k) + c1 · i + c2 · i 2 ) mod m (für i < m). I h0 ist eine übliche Hashfunktion, c1 , c2 6= 0 Konstanten. I Die Verschiebung der nachfolgende Sondierungen ist quadratisch von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. ⇒ Auch hier können m verschiedene Sequenzen erzeugt werden (wenn c1 , c2 geeignet gewählt wurden). I Das Clustering von linearem Sondieren wird vermieden. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 45/53 Hashing I Offene Adressierung Quadratisches Sondieren Hashfunktion beim quadratischen Sondieren h(k, i) = (h0 (k) + c1 · i + c2 · i 2 ) mod m (für i < m). I h0 ist eine übliche Hashfunktion, c1 , c2 6= 0 Konstanten. I Die Verschiebung der nachfolgende Sondierungen ist quadratisch von i abhängig. I Die erste Sondierung bestimmt bereits die gesamte Sequenz. ⇒ Auch hier können m verschiedene Sequenzen erzeugt werden (wenn c1 , c2 geeignet gewählt wurden). I Das Clustering von linearem Sondieren wird vermieden. I Jedoch tritt sekundäres Clustering immer noch auf: h(k, 0) = h(k 0 , 0) verursacht h(k, i) = h(k 0 , i) für alle i. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 45/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 46/53 Hashing I Offene Adressierung Doppeltes Hashing: Beispiel 22 0 1 2 15 3 4 4 ins(17) 5 1. Son28 6 dierung 7 8 31 9 10 10 22 0 1 2 15 3 4 4 ins(17) 5 2. Son28 6 dierung 7 8 31 9 10 10 h1 (k) = k mod 11 h2 (k) = 1 + k mod 10 Prof. Dr. Erika Ábrahám 22 0 1 2 15 3 4 4 ins(17) 5 3. Son28 6 dierung 7 8 31 9 10 10 22 0 1 2 15 3 4 4 ins(17) 5 4. Son28 6 dierung 7 8 31 9 10 10 22 0 1 2 15 3 4 4 5 28 6 7 17 8 31 9 10 10 h(k, i) = (h1 (k) + i · h2 (k)) mod 11 Datenstrukturen und Algorithmen 47/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 48/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. I Die erste Sondierung bestimmt nicht die gesamte Sequenz. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 48/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. I Die erste Sondierung bestimmt nicht die gesamte Sequenz. I Die Verschiebung der nachfolgende Sondierungen ist von h2 (k) abhängig. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 48/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. I Die erste Sondierung bestimmt nicht die gesamte Sequenz. I Die Verschiebung der nachfolgende Sondierungen ist von h2 (k) abhängig. ⇒ Bessere Verteilung der Schlüssel in der Hashtabelle. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 48/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. I Die erste Sondierung bestimmt nicht die gesamte Sequenz. I Die Verschiebung der nachfolgende Sondierungen ist von h2 (k) abhängig. ⇒ Bessere Verteilung der Schlüssel in der Hashtabelle. ⇒ Approximiert das gleichverteilte Hashing. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 48/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. I Die erste Sondierung bestimmt nicht die gesamte Sequenz. I Die Verschiebung der nachfolgende Sondierungen ist von h2 (k) abhängig. ⇒ Bessere Verteilung der Schlüssel in der Hashtabelle. ⇒ Approximiert das gleichverteilte Hashing. I Sind h2 (k) und m teilerfremd, wird die gesamte Hashtabelle abgesucht. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 48/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. I Die erste Sondierung bestimmt nicht die gesamte Sequenz. I Die Verschiebung der nachfolgende Sondierungen ist von h2 (k) abhängig. ⇒ Bessere Verteilung der Schlüssel in der Hashtabelle. ⇒ Approximiert das gleichverteilte Hashing. I Sind h2 (k) und m teilerfremd, wird die gesamte Hashtabelle abgesucht. I Wähle z. B. m = 2k und h2 so, dass sie nur ungerade Zahlen erzeugt. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 48/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. I Die erste Sondierung bestimmt nicht die gesamte Sequenz. I Die Verschiebung der nachfolgende Sondierungen ist von h2 (k) abhängig. ⇒ Bessere Verteilung der Schlüssel in der Hashtabelle. ⇒ Approximiert das gleichverteilte Hashing. I Sind h2 (k) und m teilerfremd, wird die gesamte Hashtabelle abgesucht. I I Wähle z. B. m = 2k und h2 so, dass sie nur ungerade Zahlen erzeugt. Jedes mögliche Paar h1 (k) und h2 (k) erzeugt eine andere Sequenz. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 48/53 Hashing I Offene Adressierung Doppeltes Hashing Hashfunktion beim doppelten Hashing h(k, i) = (h1 (k) + i · h2 (k)) mod m (für i < m). I h1 , h2 sind übliche Hashfunktionen. I Die erste Sondierung bestimmt nicht die gesamte Sequenz. I Die Verschiebung der nachfolgende Sondierungen ist von h2 (k) abhängig. ⇒ Bessere Verteilung der Schlüssel in der Hashtabelle. ⇒ Approximiert das gleichverteilte Hashing. I Sind h2 (k) und m teilerfremd, wird die gesamte Hashtabelle abgesucht. I I Wähle z. B. m = 2k und h2 so, dass sie nur ungerade Zahlen erzeugt. Jedes mögliche Paar h1 (k) und h2 (k) erzeugt eine andere Sequenz. ⇒ Daher können m2 verschiedene Permutationen erzeugt werden. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 48/53 Hashing I Offene Adressierung Praktische Effizienz vom doppelten Hashing I Hashtabelle mit 538 051 Einträgen I Mittlere Anzahl Kollisionen η pro Einfügen in die Hashtabelle: 14 Lineares Sondieren Quadratisches Sondieren Doppeltes Hashing 12 10 η 8 6 4 2 0 0 10 20 30 40 50 60 70 80 90 100 Füllgrad der Hashtabelle (in %) Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 49/53 Hashing I Offene Adressierung Effizienz der offenen Adressierung Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 50/53 Hashing I Offene Adressierung Effizienz der offenen Adressierung Unter der Annahme von gleichverteiltem Hashing gilt: Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 50/53 Hashing I Offene Adressierung Effizienz der offenen Adressierung Unter der Annahme von gleichverteiltem Hashing gilt: Erfolglose Suche Die erfolglose Suche benötigt O Prof. Dr. Erika Ábrahám 1 1−α Zeit im Average-Case. Datenstrukturen und Algorithmen 50/53 Hashing I Offene Adressierung Effizienz der offenen Adressierung Unter der Annahme von gleichverteiltem Hashing gilt: Erfolglose Suche Die erfolglose Suche benötigt O I 1 1−α Zeit im Average-Case. Bei 50% Füllung sind durchschnittlich 2 Sondierungen nötig. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 50/53 Hashing I Offene Adressierung Effizienz der offenen Adressierung Unter der Annahme von gleichverteiltem Hashing gilt: Erfolglose Suche Die erfolglose Suche benötigt O I I 1 1−α Zeit im Average-Case. Bei 50% Füllung sind durchschnittlich 2 Sondierungen nötig. Bei 90% Füllung sind durchschnittlich 10 Sondierungen nötig. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 50/53 Hashing I Offene Adressierung Effizienz der offenen Adressierung Unter der Annahme von gleichverteiltem Hashing gilt: Erfolglose Suche Die erfolglose Suche benötigt O I I 1 1−α Zeit im Average-Case. Bei 50% Füllung sind durchschnittlich 2 Sondierungen nötig. Bei 90% Füllung sind durchschnittlich 10 Sondierungen nötig. Erfolgreiche Suche Die erfolgreiche Suche benötigt O Prof. Dr. Erika Ábrahám 1 1 α · ln 1−α im Average-Case. Datenstrukturen und Algorithmen 50/53 Hashing I Offene Adressierung Effizienz der offenen Adressierung Unter der Annahme von gleichverteiltem Hashing gilt: Erfolglose Suche Die erfolglose Suche benötigt O I I 1 1−α Zeit im Average-Case. Bei 50% Füllung sind durchschnittlich 2 Sondierungen nötig. Bei 90% Füllung sind durchschnittlich 10 Sondierungen nötig. Erfolgreiche Suche Die erfolgreiche Suche benötigt O I 1 1 α · ln 1−α im Average-Case. Bei 50% Füllung sind durchschnittlich 1,39 Sondierungen nötig. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 50/53 Hashing I Offene Adressierung Effizienz der offenen Adressierung Unter der Annahme von gleichverteiltem Hashing gilt: Erfolglose Suche Die erfolglose Suche benötigt O I I 1 1−α Zeit im Average-Case. Bei 50% Füllung sind durchschnittlich 2 Sondierungen nötig. Bei 90% Füllung sind durchschnittlich 10 Sondierungen nötig. Erfolgreiche Suche Die erfolgreiche Suche benötigt O I I 1 1 α · ln 1−α im Average-Case. Bei 50% Füllung sind durchschnittlich 1,39 Sondierungen nötig. Bei 90% Füllung sind durchschnittlich 2,56 Sondierungen nötig. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 50/53 Hashing I Offene Adressierung Effizienz der offenen Adressierung Unter der Annahme von gleichverteiltem Hashing gilt: Erfolglose Suche Die erfolglose Suche benötigt O I I 1 1−α Zeit im Average-Case. Bei 50% Füllung sind durchschnittlich 2 Sondierungen nötig. Bei 90% Füllung sind durchschnittlich 10 Sondierungen nötig. Erfolgreiche Suche Die erfolgreiche Suche benötigt O I I 1 1 α · ln 1−α im Average-Case. Bei 50% Füllung sind durchschnittlich 1,39 Sondierungen nötig. Bei 90% Füllung sind durchschnittlich 2,56 Sondierungen nötig. Bei der Verkettung hatten wir Θ(1 + α) in beiden Fällen erhalten. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 50/53 Hashing I Offene Adressierung Analyse der erfolglosen Suche Annahmen I Betrachte eine zufällig erzeugte Sondierungssequenz für Schlüssel k. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 51/53 Hashing I Offene Adressierung Analyse der erfolglosen Suche Annahmen I Betrachte eine zufällig erzeugte Sondierungssequenz für Schlüssel k. I Annahme: jede mögliche Sondierungssequenz hat die gleiche 1 , da es m! mögliche Permutationen von den Wahrscheinlichkeit m! Positionen 0, . . . , m−1 gibt. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 51/53 Hashing I Offene Adressierung Analyse der erfolglosen Suche Annahmen I Betrachte eine zufällig erzeugte Sondierungssequenz für Schlüssel k. I Annahme: jede mögliche Sondierungssequenz hat die gleiche 1 , da es m! mögliche Permutationen von den Wahrscheinlichkeit m! Positionen 0, . . . , m−1 gibt. I Bemerkung: dies ist nicht unrealistisch, da im Idealfall die Sondierungssequenz für k möglichst unabhängig ist von der Sondierungssequenz für k 0 , k 6= k 0 . Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 51/53 Hashing I Offene Adressierung Analyse der erfolglosen Suche Annahmen I Betrachte eine zufällig erzeugte Sondierungssequenz für Schlüssel k. I Annahme: jede mögliche Sondierungssequenz hat die gleiche 1 , da es m! mögliche Permutationen von den Wahrscheinlichkeit m! Positionen 0, . . . , m−1 gibt. I Bemerkung: dies ist nicht unrealistisch, da im Idealfall die Sondierungssequenz für k möglichst unabhängig ist von der Sondierungssequenz für k 0 , k 6= k 0 . I Wir nehmen (wie vorher) an, dass die Berechung von Hashwerten in O(1) liegt. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 51/53 Hashing I Offene Adressierung Analyse der erfolglosen Suche Erfolglose Suche Eine Suche für k ist erfolglos wenn für i alle Slots h(k, 0), . . . , h(k, i−1) belegt sind, jedoch unterschiedlich von k sind, und h(k, i) ist unbelegt. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 52/53 Hashing I Offene Adressierung Analyse der erfolglosen Suche Erfolglose Suche Eine Suche für k ist erfolglos wenn für i alle Slots h(k, 0), . . . , h(k, i−1) belegt sind, jedoch unterschiedlich von k sind, und h(k, i) ist unbelegt. Sei X die Anzahl der belegten Positionen bis eine freie Position gefunden wird: X = min { i ∈ N | h(k, i) ist unbelegt } . Sei E [X ] der Erwartungswert von X . Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 52/53 Hashing I Offene Adressierung Analyse der erfolglosen Suche Erfolglose Suche Eine Suche für k ist erfolglos wenn für i alle Slots h(k, 0), . . . , h(k, i−1) belegt sind, jedoch unterschiedlich von k sind, und h(k, i) ist unbelegt. Sei X die Anzahl der belegten Positionen bis eine freie Position gefunden wird: X = min { i ∈ N | h(k, i) ist unbelegt } . Sei E [X ] der Erwartungswert von X . Dann: die Average-Case Komplexität einer erfolglosen Suche ist 1 + E [X ]. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 52/53 Hashing I Offene Adressierung Analyse der erfolglosen Suche Erfolglose Suche Eine Suche für k ist erfolglos wenn für i alle Slots h(k, 0), . . . , h(k, i−1) belegt sind, jedoch unterschiedlich von k sind, und h(k, i) ist unbelegt. Sei X die Anzahl der belegten Positionen bis eine freie Position gefunden wird: X = min { i ∈ N | h(k, i) ist unbelegt } . Sei E [X ] der Erwartungswert von X . Dann: die Average-Case Komplexität einer erfolglosen Suche ist 1 + E [X ]. Lemma 1 + E [X ] ∈ O 1 1−α . Beweis: im Buch. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 52/53 Hashing I Offene Adressierung Analyse der erfolgreichen Suche I Sei Schlüssel ki der i-te eingefügte Schlüssel in der Hashtabelle. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 53/53 Hashing I Offene Adressierung Analyse der erfolgreichen Suche I Sei Schlüssel ki der i-te eingefügte Schlüssel in der Hashtabelle. I Sei Xi die Anzahl der Sondierungen beim Einfügen vom Schlüssel ki . Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 53/53 Hashing I Offene Adressierung Analyse der erfolgreichen Suche I Sei Schlüssel ki der i-te eingefügte Schlüssel in der Hashtabelle. I Sei Xi die Anzahl der Sondierungen beim Einfügen vom Schlüssel ki . I Die Suche für ki braucht im Mittel E [Xi ] Zeiteinheiten. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 53/53 Hashing I Offene Adressierung Analyse der erfolgreichen Suche I Sei Schlüssel ki der i-te eingefügte Schlüssel in der Hashtabelle. I Sei Xi die Anzahl der Sondierungen beim Einfügen vom Schlüssel ki . I Die Suche für ki braucht im Mittel E [Xi ] Zeiteinheiten. I Die Average-Case Zeitkomplexität für eine erfolgreiche Suche ist: X 1 n−1 E [Xi+1 ]. n i=0 Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 53/53 Hashing I Offene Adressierung Analyse der erfolgreichen Suche I Sei Schlüssel ki der i-te eingefügte Schlüssel in der Hashtabelle. I Sei Xi die Anzahl der Sondierungen beim Einfügen vom Schlüssel ki . I Die Suche für ki braucht im Mittel E [Xi ] Zeiteinheiten. I Die Average-Case Zeitkomplexität für eine erfolgreiche Suche ist: X 1 n−1 E [Xi+1 ]. n i=0 Lemma 1 n Pn−1 i=0 E [Xi+1 ] ∈ O 1 1 α · ln 1−α . Beweis: im Buch. Prof. Dr. Erika Ábrahám Datenstrukturen und Algorithmen 53/53