Es gibt verschiedene Techniken, die sicherstellen, dass Suchvorgänge auch im schlimmsten Fall immer O (1) -Operationen erfordern.
Wie kann ich feststellen, ob eine Hash-Tabelle eine Chance auf O (1) -Operationen hat und welche Techniken möglicherweise für meine Hash-Funktion verwendet werden?
Der schlimmste Fall tritt ein, wenn ein böswilliger Angreifer (Mallory) Ihnen absichtlich Daten zur Verfügung stellt, die Mallory speziell ausgewählt hat, um das System langsam laufen zu lassen.
Sobald Sie eine bestimmte Hash-Funktion ausgewählt haben, ist es wahrscheinlich zu optimistisch anzunehmen, dass Mallory nie herausfinden wird, welche Hash-Funktion Sie ausgewählt haben. Sobald Mallory feststellt, welche Hash-Funktion Sie ausgewählt haben, können Sie mit Mallory viele Daten in Ihre Hash-Tabelle einfügen. Dann sind Sie zum Scheitern verurteilt: Mallory kann intern schnell Milliarden von Datenelementen generieren und diese mit Ihren Hash-Daten versehen Die Hash-Funktion ermittelt, welche Datenelemente wahrscheinlich kollidieren, und füttert Sie dann mit Millionen von Eins-zu-Tausend-Datenelementen, die wahrscheinlich kollidieren. Dies führt zu Suchvorgängen, die viel langsamer als O (1) ausgeführt werden.
Alle Techniken, die "O (1) Lookups auch im schlimmsten Fall" garantieren, vermeiden dieses Problem, indem Sie ein wenig zusätzliche Arbeit an jeder Einfügung leisten, um zu gewährleisten, dass in Zukunft jede mögliche Suche in O (1) -Zeit erfolgreich sein kann . Insbesondere nehmen wir an (schlimmster Fall), dass Mallory früher oder später herausfinden wird, welche Hash-Funktion wir verwenden; Er hat jedoch nur die Möglichkeit, einige Datenelemente einzufügen, bevor wir eine andere Hash-Funktion auswählen - Tabellierungs-Hashing oder eine andere universelle Hashing-Funktion -, die wir speziell auswählen, damit alle Daten, die wir bisher haben, in 2 nachgeschlagen werden können oder 3 Sonden - dh O (1). Da wir diese Funktion zufällig auswählen, können wir ziemlich sicher sein, dass Mallory für eine Weile nicht weiß, welche Funktion wir ausgewählt haben. Auch wenn MalloryGibt uns sofort Daten, die selbst mit dieser neuen Hash-Funktion mit früheren Daten kollidieren, können wir dann noch eine neue Hash-Funktion auswählen, so dass nach dem erneuten Aufbereiten alle früheren Daten, die er und alle anderen uns zugeführt haben, jetzt angezeigt werden können in 2 oder 3 Sonden im schlimmsten Fall - dh O (1) Lookups im schlimmsten Fall.
Es ist ziemlich einfach, eine neue Hash-Funktion zufällig auszuwählen und die gesamte Tabelle häufig genug zu überarbeiten, um sicherzustellen, dass jede Suche immer O (1) ist. Während dies garantiert, dass jede Suche immer O (1) ist, können diese Techniken beim Einfügen des N-ten Elements in eine Hash-Tabelle, die bereits N-1 Elemente enthält, gelegentlich O (N) Zeit für diese Einfügung erfordern. Es ist jedoch möglich, das System so zu gestalten, dass, selbst wenn Mallory Ihnen absichtlich neue Daten gibt, die mit der neuen Hash-Funktion mit früheren Daten kollidieren, das System viele Elemente von Mallory und anderen akzeptieren kann, bevor es eine Aktion ausführen muss vollständiger O (N) Umbau. Hashtabellentechniken, die eine neue Funktion auswählen und erneut aufbereiten, um O (1) -Suchvorgänge auch im schlimmsten Fall zu gewährleisten, umfassen:
- Kuckuck-Hashing garantiert, dass jede Schlüsselsuche mit höchstens 2 Hash-Berechnungen und 2 Tabellensuchen erfolgreich ist.
- Hopscotch-Hashing garantiert, dass jede Schlüsselsuche erfolgreich ist, nachdem bei einer kleinen Anzahl von H (möglicherweise H = 32) aufeinanderfolgenden Einträgen in der Tabelle geprüft wurde .
- dynamisches, perfektes Hashing - das Papier von Dietzfelbinger aus dem Jahr 1994 ist das erste, das ich gelesen habe und das darauf hinwies, dass es möglich ist, auch wenn es "häufig" wiederholt wird, um zu gewährleisten, dass jede Schlüsselsuche mit zwei Hash-Berechnungen und zwei Nachschlägen immer erfolgreich ist eine vollständige Wiederaufbereitung so selten durchzuführen, dass die erwarteten durchschnittlichen Kosten für das Einfügen und Löschen von Daten, obwohl bei jeder vollständigen Wiederaufbereitung O (n) -Zeit erforderlich ist, O (1) amortisiert werden.
Datenstrukturen / Hash-Tabellen