Złożoność runtime tabeli Hash (wstawianie, wyszukiwanie i usuwanie)

Dlaczego ciągle widzę różne złożoności runtime dla tych funkcji w tabeli hash?

Na wiki, search and delete to O (N) (myślałem, że celem tabel hashowych jest stałe wyszukiwanie, więc o co chodzi, jeśli search to O (n)).

W niektórych notatkach z kursu sprzed jakiegoś czasu, widzę szeroki zakres złożoności w zależności od pewnych szczegółów, w tym jeden ze wszystkimi O (1). Po co miałaby być użyta jakakolwiek inna implementacja, jeśli Mogę uzyskać wszystkie O(1)?

Jeśli używam standardowego hasha tabele w języku takim jak C++ czy Java, czego mogę się spodziewać?

Author: amit, 2012-02-09

5 answers

Tabele HashO(1) średnia i amortyzowana złożoność sprawy, jednak cierpi na O(n) w najgorszym przypadku złożoność czasu.

Tabele Hash cierpią z powodu O(n) najgorszej złożoności czasowej z dwóch powodów:

  1. Jeśli zbyt wiele elementów zostało zahaszowanych do tego samego klucza: zajrzenie do wnętrza tego klucza może zająć O(n) czas.
  2. gdy tabela hash przejdzie load balance - to musi ponownie [utworzyć nową większą tabelę i ponownie wstawić każdy element do tabeli].

Mówi się jednak, że jest to O(1) przypadek średni i amortyzowany, ponieważ:

  1. bardzo rzadko zdarza się, że wiele elementów zostanie zahaszowanych do tego samego klucza [jeśli wybrałeś dobrą funkcję haszującą i nie masz zbyt dużego balansu obciążenia.
  2. operacja rehash, która jest O(n), może nastąpić co najwyżej po n/2 ops, które są wszystkie przyjęte O(1): więc kiedy zsumujesz średni czas na op, otrzymujesz : (n*O(1) + O(n)) / n) = O(1)

Uwaga z powodu problemu z odświeżaniem - aplikacji w czasie rzeczywistym i aplikacji, które wymagają niskiego opóźnienia - nie powinny używać tabeli hash jako struktury danych.

EDIT: Annother issue with hash tables: cache
kolejny problem, w którym można zobaczyć utratę wydajności w dużych tabel hash, jest spowodowany wydajnością pamięci podręcznej. tabele Hash cierpią z powodu złej wydajności pamięci podręcznej, a więc dla dużych kolekcji - czas dostępu może trwa to dłużej, ponieważ musisz ponownie załadować odpowiednią część tabeli z pamięci z powrotem do pamięci podręcznej.

 65
Author: amit,
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
2015-12-31 18:02:33

Idealnie, hashtable to O(1). Problem polega na tym, że dwa klucze nie są sobie równe, jednak powodują ten sam hash.

Na przykład, wyobraź sobie ciągi "to był najlepszy czas, to był najgorszy czas" i "zielone jajka i szynka" oba dały wartość skrótu 123.

Po włożeniu pierwszego Sznurka wkłada się go do wiadra 123. Gdy drugi łańcuch jest wstawiany, zobaczy, że wartość dla bucket 123 już istnieje. Następnie porównałby nowe wartość do istniejącej wartości, i zobaczyć, że nie są równe. W takim przypadku dla tego klucza zostanie utworzona tablica lub lista powiązana. W tym momencie pobranie tej wartości staje się O(n), ponieważ hashtable musi przejrzeć każdą wartość w tym wiadrze, aby znaleźć żądaną.

Z tego powodu, podczas korzystania z tabeli skrótów, ważne jest, aby użyć klucza z naprawdę dobrą funkcją skrótu, która jest zarówno Szybka, jak i często nie powoduje powielania wartości dla różnych obiektów.

Ma sens?

 13
Author: Mike Christensen,
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
2012-02-09 16:15:07
 3
Author: Demi,
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
2018-09-05 01:13:37

Zależy od tego, jak zaimplementujesz hashowanie, w najgorszym przypadku może przejść do O(n), w najlepszym przypadku jest to 0(1) (ogólnie można osiągnąć, jeśli twój DS nie jest tak duży łatwo)

 2
Author: Jigar Joshi,
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
2012-02-09 16:06:47

Być może patrzyłeś na złożoność przestrzeni? To jest O (n). Pozostałe zawiłości są zgodne z oczekiwaniami w tabeli hash . Złożoność wyszukiwania zbliża się do O (1) wraz ze wzrostem liczby kubełków. Jeśli w najgorszym przypadku masz tylko jedno wiadro w tabeli hash, to złożoność wyszukiwania wynosi O (n).

Edit w odpowiedzi na komentarz nie wydaje mi się, aby słuszne było stwierdzenie O(1) to Przeciętny przypadek. Naprawdę jest (jak mówi strona Wikipedii) O (1+n/k) gdzie k jest wielkość tabeli hash. Jeśli K jest wystarczająco duże, to wynikiem jest efektywnie O(1). Ale załóżmy, że K jest 10, A N jest 100. W takim przypadku każde wiadro będzie miało średnio 10 wpisów, więc czas wyszukiwania zdecydowanie nie wynosi O(1); jest to wyszukiwanie liniowe do 10 wpisów.

 2
Author: Mark Wilkins,
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
2012-02-09 16:22:07