Временная сложность операции Hashmap get () и put () - это O (1) во все времена [дублировать]

1) удалить Netbeans & amp; скачать JDK 8 http://www.oracle.com/technetwork/java/javase/downloads/index.html from Here

2) Извлечь JDK в / home / username /

3) Загрузите Netbeans https://netbeans.org/downloads/

4) Установите Netbeans из терминала, следуя за этим tutorial

5) Установка запрашивает местоположение jdk, затем просматривает /home/username/jdk1.8.0_91

проблема решена .....

90
задан Michael 29 December 2010 в 12:40
поделиться

6 ответов

Это зависит от многих вещей. Обычно это O (1) с приличным хешем, который сам по себе является постоянным временем ... но вы можете иметь хэш, который занимает много времени, чтобы вычислить и , если представляют собой несколько элементов в хэш-карте, которые возвращают один и тот же хэш-код, get должны будут перебирать их, вызывая equals для каждого из них, чтобы найти совпадение.

В худшем случае HashMap имеет поиск O (n) из-за прохождения через все записи в том же ведро хэша (например, если все они имеют один и тот же хеш-код). К счастью, этот худший сценарий не возникает очень часто в реальной жизни, по моему опыту. Таким образом, нет, O (1), конечно, не гарантируется, но обычно это следует учитывать при рассмотрении того, какие алгоритмы и структуры данных использовать.

В JDK 8 HashMap была изменена так, что если ключи могут быть сопоставлены для упорядочения, тогда любое густонаселенное ведро реализуется как дерево, так что даже если есть много записей с одним и тем же хеш-кодом, сложность O (log n). Это может вызвать проблемы, если у вас есть тип ключа, в котором равенство и порядок отличаются, конечно.

И да, если у вас недостаточно памяти для хэш-карты, у вас будут проблемы. .. но это будет правда, какая структура данных вы используете.

153
ответ дан Jon Skeet 17 August 2018 в 14:15
поделиться
  • 1
    @marcog: Вы предполагаете, что O (n log n) для одиночного поиска ? Это звучит глупо для меня. Разумеется, это будет зависеть от сложности функций хэша и равенства, но это вряд ли будет зависеть от размера карты. – Jon Skeet 29 December 2010 в 12:29
  • 2
    @marcog: Итак, что вы предполагаете быть O (n log n)? Вставка n элементов? – Jon Skeet 29 December 2010 в 12:40
  • 3
    +1 за хороший ответ. Не могли бы вы предоставить ссылки, например , эту запись в википедии для хэш-таблицы в вашем ответе? Таким образом, более заинтересованный читатель мог бы добраться до ничтожного понимания why , который вы дали свой ответ. – Weiser 29 December 2010 в 16:19
  • 4
    это не относится к JDK 1.8, но stackoverflow.com/a/34551054/822588 – Sleiman Jneidi 31 December 2015 в 20:54
  • 5
    @SleimanJneidi: все равно, если ключ не реализует Comparable & lt; T & gt; `, но я обновляю ответ, когда у меня будет больше времени. – Jon Skeet 1 January 2016 в 02:07

На практике это O (1), но на самом деле это ужасное и математически неосмысленное упрощение. Обозначение O () говорит о том, как работает алгоритм, когда размер проблемы стремится к бесконечности. Hashmap get / put работает как алгоритм O (1) для ограниченного размера. Предел достаточно велик из памяти компьютера и с точки зрения адресации, но далеко от бесконечности.

Когда кто-то говорит, что hashmap get / put равен O (1), он должен действительно сказать, что необходимое время поскольку get / put более или менее постоянна и не зависит от количества элементов в хэш-карте, поскольку хэш-карта может быть представлена ​​в реальной вычислительной системе. Если проблема выходит за пределы этого размера, и нам нужны большие хешмапы, то через некоторое время число бит, описывающее один элемент, также будет увеличиваться по мере того, как мы исчерпываем возможные описываемые различные элементы. Например, если мы использовали хэш-карту для хранения 32-битных номеров, а затем увеличиваем размер проблемы, чтобы в хэш-карте было больше 2 ^ 32-битных элементов, тогда отдельные элементы будут описаны с более чем 32 битами.

Число бит, необходимых для описания отдельных элементов, это log (N), где N - максимальное количество элементов, поэтому get и put действительно O (log N).

Если вы сравниваете его с набором деревьев, который является O (log n), тогда хэш-набор равен O (long (max (n)), и мы просто чувствуем, что это O (1), потому что на некоторой реализации max (n) фиксированный, не изменяется (размер хранимых объектов измеряется в битах), и алгоритм, вычисляющий хэш-код, выполняется быстро.

Наконец, если поиск элемента в любой структуре данных был O (1), мы будет создавать информацию из воздуха. Имея структуру данных из n элемента, я могу выбрать один элемент n различными способами, при этом я могу кодировать информацию о битах (n) .Если я могу кодировать это в нулевом бите (то есть wh в O (1) означает), то я создал бесконечно сжатый ZIP-алгоритм.

1
ответ дан Peter Verhas 17 August 2018 в 14:15
поделиться

Операция HashMap является зависимым фактором реализации hashCode. Для идеального сценария можно сказать, что хорошая хэш-реализация, которая предоставляет уникальный хеш-код для каждого объекта (отсутствие хеш-коллизии), тогда лучшим, худшим и средним сценарием будет O (1). Рассмотрим сценарий, когда плохая реализация hashCode всегда возвращает 1 или такой хеш, который имеет хеш-коллизию. В этом случае временной сложностью будет O (n).

Теперь, перейдя ко второй части вопроса о памяти, тогда да, ограничение памяти будет зависеть от JVM.

7
ответ дан Pranav 17 August 2018 в 14:15
поделиться

Уже упоминалось, что hashmaps являются O(n/m) в среднем, если n - количество элементов, а m - размер. Также было упомянуто, что в принципе все это может рухнуть в единый список с запросом времени O(n). (Это все предполагает, что вычисление хеша является постоянным временем).

Однако то, что не часто упоминается, заключается в том, что с вероятностью не менее 1-1/n (так что для 1000 предметов, что является шансом 99,9%) наибольший ведро не будет заполнено больше, чем O(logn)! Следовательно, соответствие средней сложности двоичных деревьев поиска. (И константа хороша, более жесткая привязка - (log n)*(m/n) + O(1)).

Все, что требуется для этой теоретической оценки, состоит в том, что вы используете достаточно хорошую хеш-функцию (см. Википедия: Универсальная хэширование . Это может быть так же просто, как a*x>>m). И конечно, что человек, дающий вам значения хешу, не знает, как вы выбрали ваши случайные константы.

TL; DR: С очень высокой вероятностью худший случай get / put сложность хэш-карты O(logn).

7
ответ дан Thomas Ahle 17 August 2018 в 14:15
поделиться
  • 1
    (И заметим, что ни одно из этого не предполагает случайных данных. Вероятность возникает исключительно из выбора хэш-функции) – Thomas Ahle 6 October 2014 в 09:18
  • 2
    У меня также есть тот же вопрос, связанный с сложностью выполнения в хэш-карте. Казалось бы, это O (n), поскольку предполагается, что постоянные факторы будут отброшены. 1 / m является постоянным множителем и, таким образом, падает, оставляя O (n). – nickdu 6 April 2017 в 23:25

Я не уверен, что hashcode по умолчанию является адресом - я читал исходный код OpenJDK для генерации hashcode некоторое время назад, и я помню, что это было что-то более сложное. По-видимому, это не то, что гарантирует хорошее распределение. Тем не менее, это в некоторой степени спорным, так как несколько классов, которые вы будете использовать в качестве ключей в HashMap использовать хэш-код по умолчанию -. Они предоставляют свои собственные реализации, которые должны быть хорошо

Кроме того, что вы можете не знать (опять же, это основано на источнике чтения - это не гарантировано) заключается в том, что HashMap перемешивает хэш перед его использованием, смешивая энтропию из всего слова в нижние биты, где он необходим всем, кроме самые большие хэшмапы. Это помогает справиться с хэшами, которые специально не делают этого сами, хотя я не могу думать о каких-либо распространенных случаях, где вы это увидите.

Наконец, что происходит, когда таблица перегружена, так это то, что она вырождается в набор параллельных связанных списков - производительность становится O (n). В частности, количество пройденных связей будет в среднем составлять половину коэффициента загрузки.

9
ответ дан Tom Anderson 17 August 2018 в 14:15
поделиться
  • 1
    Проклятье. Я решил поверить, что если бы мне не пришлось набирать этот текст на сенсорном экране мобильного телефона, я мог бы избить Jon Sheet до удара. Для этого есть значок, верно? – Tom Anderson 29 December 2010 в 12:55
0
ответ дан Konstantinos Chalkias 29 October 2018 в 16:16
поделиться