Wie gehen HashTables mit Kollisionen um?
Ich habe gehört, in meinem Abschluss-Klassen, die eine HashTable
wird ein neuer Eintrag in die 'nächste verfügbare' Eimer, wenn Sie den neuen Schlüssel-Eintrag kollidiert mit einem anderen.
Wie würde der HashTable
noch den richtigen Wert zurück, wenn diese Kollision tritt auf, beim aufrufen für ein zurück bei der Kollision Schlüssel?
Ich gehe davon aus, dass die Keys
sind String
Typ und die hashCode()
gibt die standardmäßig generiert, indem Sie sagen, Java.
Wenn ich setze meine eigene Hash-Funktion, und verwenden Sie es als Teil einer look-up-Tabelle (d.h. eine HashMap
oder Dictionary
), welche Strategien existieren für den Umgang mit Kollisionen?
Habe ich gesehen, auch Hinweise in Bezug auf Primzahlen! Informationen, die nicht so klar aus der Google-Suche.
InformationsquelleAutor der Frage Alex | 2011-02-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hash-Tabellen Umgang mit Kollisionen in einer von zwei Möglichkeiten.
Option 1:, Indem jeder bucket enthält eine verknüpfte Liste von Elementen, die gehasht werden, dass Eimer. Dies ist der Grund, warum eine schlechte hash-Funktion können suchen in hash-Tabellen sehr langsam.
Option 2:, Wenn der hash-Tabelleneinträge sind alle voll dann der hash-Tabelle kann eine Erhöhung der Anzahl der buckets, die es hat, und dann verteilen Sie alle Elemente in der Tabelle. Die hash-Funktion liefert eine ganze Zahl, und die hash-Tabelle ist das Ergebnis der hash-Funktion und mod es mit der Größe der Tabelle, so kann es sicher sein, es wird bekommen, um Eimer. So durch die Erhöhung der Größe, wird es sofort wieder, und führen Sie die modulo-Berechnungen, die, wenn Sie Glück haben, vielleicht schicken Sie die Objekte auf unterschiedliche buckets.
Java verwendet sowohl option 1 und 2 in seiner hash-Tabelle Implementierungen.
InformationsquelleAutor der Antwort ams
Wenn Sie Sprach über die "Hash-Tabelle wird ein neuer Eintrag in die 'nächste verfügbare' Eimer, wenn Sie den neuen Schlüssel-Eintrag kollidiert mit einem anderen.", Sie sprechen über die Offene Adressierung Strategie der kollisionsauflösung der hash-Tabelle.
Gibt es mehrere Strategien für die hash-Tabelle zu beheben Kollision.
Erste Art von groß-Methode müssen die Tasten (oder Zeiger) werden in der Tabelle gespeichert, zusammen mit den dazugehörigen Werten, die weiter umfasst:
Eine weitere wichtige Methode, mit der Kollision von Dynamische Größenanpassung, welche weiteren hat mehrere Möglichkeiten:
BEARBEITEN: die oben genannten entlehnt sind wiki_hash_table, wo Sie gehen sollten, um zu schauen um mehr Infos zu bekommen.
InformationsquelleAutor der Antwort herohuyongtao
Ich empfehle Ihnen das Lesen dieses blog-post erschienen auf HackerNews vor kurzem:
Wie HashMap in Java funktioniert
Kurz gesagt, die Antwort ist
InformationsquelleAutor der Antwort zengr
Gibt es mehrere Techniken zur Verfügung, damit Kollision. Ich werde erklären, einige von Ihnen
Verkettung:
In Verkettung verwenden wir die array-Indizes, um die Werte zu speichern. Wenn der hash-code der zweite Wert auch die Punkte an den gleichen index, dann ersetzen wir das index-Wert mit einer verknüpften Liste und alle Werte zeigen auf, dass der index gespeichert werden, die in der verknüpften Liste und der tatsächlichen array-index-Punkte auf den Kopf der verketteten Liste.
Aber wenn es nur einen hash-code verweist auf einen index des Arrays wird der Wert direkt gespeichert, index. Dieselbe Logik wird angewendet, während das abrufen von Werten. Dies wird in Java HashMap/Hashtable Kollisionen sind zu vermeiden.
Linear probing: Diese Technik wird verwendet, wenn wir mehr index in der Tabelle dann die Werte gespeichert werden. Linear probing-Technik die Arbeit an das Konzept halten, Inkrementieren, bis Sie den leeren Steckplatz ein. Der pseudo-code sieht wie folgt aus..
index = h(k)
while( val(index) belegt ist)
index = (index+1) mod n
Double-hashing-Technik: In dieser Technik, die wir benutzen zwei Hashfunktionen h1(k) und h2(k). Wenn der Schlitz bei h1(k) besetzt ist, dann wird der zweite Hash-Funktion h2(k) zum Inkrementieren der index. Der pseudo-code sieht wie folgt aus..
index = h1(k)
while( val(index) belegt ist)
index = (index + h2(k)) mod n
Linear probing und double hashing-Techniken sind Teil der offenen Adressierung Technik, und es kann nur verwendet werden, wenn die verfügbaren Steckplätze sind mehr als die Anzahl der Elemente Hinzugefügt werden. Es dauert weniger Speicher, dann chaining, weil es keine zusätzliche Struktur verwendet, die hier aber seine langsam, weil viel Bewegung passieren, bis wir finden einen leeren slot. Auch in der offenen Adressierung die Verfahren, wenn ein Element entfernt wird, ein Ablagefach legen wir den Grabstein, um anzuzeigen, dass das Objekt entfernt ist von hier, dass ist der Grund, warum seine leere.
Entnommen http://coder2design.com/hashing/
InformationsquelleAutor der Antwort Jatinder Pal
Dies ist eigentlich nicht stimmt, zumindest für die Oracle-JDK (es ist eine Implementierung detail, das kann variieren zwischen den verschiedenen Implementierungen der API). Statt dessen wird jeder bucket enthält eine verkettete Liste von Einträgen.
Es nutzt die
equals()
zu finden der wirklich passenden Eintrag.Gibt es verschiedene collision-handling-Strategien mit verschiedenen vor-und Nachteile.
Wikipedia-Eintrag auf hash-Tabellen gibt einen guten überblick.
InformationsquelleAutor der Antwort Michael Borgwardt
Da es einige Verwirrung darüber, welcher Algorithmus der Java-HashMap ist (in der Sun/Oracle/OpenJDK-Implementierung), hier der relevante Quellcode-Schnipsel (von OpenJDK, 1.6.0_20, auf Ubuntu):
Diese Methode (zitieren ist aus Linien, 355 bis 371) wird aufgerufen, wenn nach einem Eintrag in der Tabelle, zum Beispiel von
get()
,containsKey()
und einige andere. Die for-Schleife geht hier über die verlinkten Liste gebildet, die durch die Eingabe-Objekte.Hier der code für den Eintrag Objekte (Linien 691-705 + 759):
Direkt danach kommt der
addEntry()
Methode:Diese fügt den neuen Eintrag auf der Vorderseite des Eimers, mit einem link zu der alten ersten Eintrag (oder null, wenn kein solches). In ähnlicher Weise werden die
removeEntryForKey()
- Methode durchläuft die Liste und kümmert sich um das löschen nur eines Eintrags, so dass der rest der Liste intakt.So, hier ist eine verknüpfte Liste für jeden Eimer, und ich sehr bezweifle, dass dies geändert
_20
zu_22
, da war es so von 1,2 auf.(Dieser code ist (c) 1997-2007 Sun Microsystems, und unter GPL verfügbar, aber für das kopieren besser, die original-Datei, enthalten in src.zip in jedem JDK von Sun/Oracle, und auch in OpenJDK.)
InformationsquelleAutor der Antwort
Wird, verwenden Sie die equals-Methode, um zu sehen, ob der Schlüssel vorhanden ist, auch und besonders dann, wenn mehr als ein element in der gleichen Eimer.
InformationsquelleAutor der Antwort Hovercraft Full Of Eels
Gibt es verschiedene Methoden für die kollisionsauflösung.Einige von Ihnen sind Separate Chaining,Offene Adressierung,Robin-Hood-hashing,Cuckoo Hashing etc.
Java verwendet Separate Chaining für die Auflösung von Kollisionen in Hash-Tabellen.Hier ist ein toller link, wie es passiert:
http://javapapers.com/core-java/java-hashtable/
InformationsquelleAutor der Antwort Infusion of Wormwood n Asfodel
hier ist eine sehr einfache hash-Tabelle-Implementierung in java. in nur implementiert
put()
undget()
, aber Sie können hinzufügen, was Sie wollen. es basiert auf javahashCode()
Methode wird implementiert, indem alle Objekte. Sie könnte einfach erstellen Sie Ihre eigene Oberfläche,und mit Gewalt umgesetzt werden, indem die Tasten, wenn Sie möchten.
InformationsquelleAutor der Antwort Jeffrey Blattman