Czym są Hashtable i hashmapy oraz ich typowe przypadki użycia?

Ostatnio natknąłem się na te terminy kilka razy, ale jestem dość zdezorientowany, jak one działają i kiedy są zwykle wdrażane?

Author: John Topley, 2008-09-26

4 answers

Pomyśl o tym w ten sposób.

Jeśli używasz tablicy, prostej struktury danych opartej na indeksach i wypełniasz ją losowymi rzeczami, znalezienie konkretnego wpisu staje się coraz droższą operacją, gdy wypełniasz go danymi, ponieważ w zasadzie musisz zacząć szukać od jednego końca do drugiego, aż znajdziesz ten, którego chcesz.

Jeśli chcesz uzyskać szybszy dostęp do danych, typicall uciekają się do sortowania tablicy i za pomocą wyszukiwania binarnego. To jednak, przy jednoczesnym zwiększeniu szybkość wyszukiwania istniejącej wartości sprawia, że wstawianie nowych wartości jest powolne, ponieważ trzeba przesuwać istniejące elementy wokół, gdy trzeba wstawić element w środku.

Z drugiej strony, hashtable ma powiązaną funkcję, która przyjmuje wpis i redukuje go do liczby, klucza hashowego. Ta liczba jest następnie używana jako indeks do tablicy i to jest miejsce, w którym zapisujesz wpis.

Tablica hashtable obraca się wokół tablicy, która początkowo zaczyna się od pustej. Pusty nie znaczy zerowa długość, tablica zaczyna się od rozmiaru, ale wszystkie elementy w tablicy nie zawierają nic.

Każdy element ma dwie właściwości, Dane i klucz, który identyfikuje dane. Na przykład, lista kodów pocztowych USA byłaby typem skojarzenia zip-code -> name. Funkcja zmniejsza klucz, ale nie uwzględnia danych.

Więc gdy wstawisz coś do tablicy hashtable, funkcja zmniejsza klucz do liczby, która jest używana jako indeks do tej (pustej) tablicy, i tutaj przechowujesz dane, zarówno klucz, jak i Powiązane Dane.

Następnie, później, chcesz znaleźć konkretny wpis, do którego znasz klucz, więc uruchom klucz za pomocą tej samej funkcji, uzyskaj jego klucz hashowy,i przejdź do tego konkretnego miejsca w hashtable i pobiera tam dane.

Teoria głosi, że funkcja, która redukuje Twój klucz do klucza hashowego, tej liczby, jest obliczeniowo znacznie tańsza niż wyszukiwanie liniowe.

Typowy hashtable nie mają nieskończoną liczbę elementów dostępnych do przechowywania, więc liczba jest zwykle zmniejszana do indeksu, który pasuje do rozmiaru tablicy. Jednym ze sposobów na to jest po prostu pobranie modułu indeksu w porównaniu z rozmiarem tablicy. Dla tablicy o rozmiarze 10, indeks 0-9 będzie mapował bezpośrednio do indeksu, A Indeks 10-19 będzie mapował ponownie do 0-9 i tak dalej.

Niektóre klucze zostaną zredukowane do tego samego indeksu, co istniejący wpis w tabeli hashtable. W tym momencie rzeczywiste klucze są porównywane bezpośrednio, ze wszystkimi regułami związanymi z porównywaniem typów danych klucza (np. na przykład zwykłe porównanie łańcuchów). Jeśli istnieje pełne dopasowanie, albo ignorujesz nowe dane (już istnieją), albo nadpisujesz (zastępujesz stare dane dla tego klucza), albo dodajesz je (wielowartościowa hashtable). Jeśli nie ma dopasowania, co oznacza, że chociaż klucze hash były identyczne, rzeczywiste klucze nie były, zazwyczaj znajdujesz nową lokalizację do przechowywania tego klucza+danych do środka.

Rozwiązywanie kolizji ma wiele implementacji, a najprostszą z nich jest przejście do następnego pustego elementu w tablicy. To proste rozwiązanie ma jednak inne problemy, więc znalezienie odpowiedniego algorytmu rozdzielczości jest również dobrym ćwiczeniem dla hashtables.

Hashtables mogą również rosnąć, jeśli wypełniają się całkowicie (lub są blisko), i zwykle odbywa się to poprzez utworzenie nowej tablicy o nowym rozmiarze, ponowne obliczenie wszystkich indeksów i umieszczenie elementów w nowej tablicy w nowych lokalizacjach.

Funkcja redukująca klucz do liczby nie daje wartości liniowej, tj. "AAA "staje się 1, A" AaB " staje się 2, więc hashtable nie jest sortowany według żadnej typowej wartości.

Na ten temat jest również dostępny dobry artykuł w Wikipedii, tutaj .

 67
Author: Lasse Vågsæther Karlsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 08:38:11

Odpowiedź Lassevka jest bardzo dobra, ale może zawierać zbyt wiele szczegółów. Oto streszczenie. Celowo pomijam pewne istotne informacje, które możesz bezpiecznie ignorować przez 99% czasu.

Nie mażadnej ważnej różnicy między tabelami hash a mapami hashowymi w 99% przypadków.

Tabele Hash są magiczne

Poważnie. To magiczna struktura danych, która oprócz gwarantuje trzy rzeczy . (Są wyjątki. Ty może je w dużej mierze ignorować, chociaż uczenie się ich kiedyś może być dla Ciebie przydatne.)

1) Wszystko w tabeli hash jest częścią pary - istnieje klucz i wartość . Wprowadzasz i wyciągasz dane, określając klucz, na którym operujesz.

2) jeśli robisz cokolwiek za pomocą jednego klawisza na tablicy hash, jest to niesamowicie szybkie . Oznacza to, że put(key,value), get(key), contains(key), i są naprawdę szybkie.

3) Ogólne tabele hash fail at robienie czegokolwiek nie wymienionego w #2 ! (Przez "fail" rozumiemy, że są niesamowicie powolne.)

Kiedy używamy tabel hash?

Używamy tabel hash , gdy ich magia pasuje do naszego problemu.

Na przykład, buforowanie często kończy się użyciem tabeli hash-na przykład, załóżmy, że mamy 45 000 studentów na uniwersytecie i niektóre procesy muszą przechowywać rekordy dla wszystkich z nich. Jeśli rutynowo odnosisz się do ucznia po numerze ID, to ID => student cache sprawia, że doskonałe sens. Operacja, którą optymalizujesz dla tego bufora to fast lookup .

Hasze są również niezwykle przydatne doprzechowywania relacji między danymi , gdy nie chcesz iść cały Wieprz i zmieniać samych obiektów. Na przykład, podczas rejestracji na kurs, może być dobrym pomysłem, aby być w stanie odnieść uczniów do zajęć, które biorą. Jednak z jakiegokolwiek powodu możesz nie chcieć, aby sam obiekt ucznia o tym wiedział. Użyj studentToClassRegistration hash i trzymaj go przy sobie, podczas gdy robisz to, co musisz zrobić.

Robią również dość dobry pierwszy wybór dla struktury danych z wyjątkiem sytuacji, gdy trzeba zrobić jedną z następujących czynności:

Kiedy Nie Używać Tabel Hash

Iteracja nad elementami . Tabele Hash zazwyczaj nie robią iteracji zbyt dobrze. (Rodzajowe, czyli Poszczególne implementacje czasami zawierają listy połączone, które są używane do tego, aby iteracja nad nimi była mniejsza. Na przykład w Java, LinkedHashMap pozwala szybko iterować nad kluczami lub wartościami.)

Sortowanie. Jeśli nie możesz iterować, sortowanie też jest królewskim bólem.

Przejście od wartości do klucza . Użyj dwóch tabel hashowych. Uwierz mi, oszczędziłem Ci bólu.

 50
Author: Patrick McKenzie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 09:33:09

Jeśli mówimy o Javie, obie są kolekcjami, które pozwalają na dodawanie, usuwanie i aktualizowanie obiektów oraz wewnętrznie wykorzystują algorytmy Hasingowe.

Znacząca różnica, jeśli mówimy o Javie, polega na tym, że Hashtable są z natury zsynchronizowane i dlatego są bezpieczne dla wątków, podczas gdy mapy hashowe nie są bezpieczną kolekcją wątków.

Oprócz synchronizacji, wewnętrzny mechanizm przechowywania i pobierania obiektów jest hashujący zarówno w sprawy.

Jeśli chcesz zobaczyć, jak działa haszowanie, polecam trochę googlowania o strukturach danych i technikach haszowania.

 4
Author: Nrj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 08:30:49

Hashtables / hashmaps kojarzą wartość (zwaną "kluczem" dla celów disambiguacji) z inną wartością. Można je traktować jako rodzaj słownika (słowo: definicja) lub rekordu bazy danych (klucz: dane).

 -2
Author: tzot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 08:26:37