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ć?
5 answers
Tabele Hash są O(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:
- 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. - 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ż:
- 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.
- operacja rehash, która jest
O(n)
, może nastąpić co najwyżej pon/2
ops, które są wszystkie przyjęteO(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.
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?
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
Niektóre tabele hash (} mają zagwarantowane o (1) lookup
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)
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.
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