Какова сложность времени для доступа / поиска корзины HashMap (не значение в корзине)? - PullRequest
0 голосов
/ 28 ноября 2018

Предположим, у нас есть два разных hashMaps, например map1 и map2.

  • map1 имеет 1000 записей с 1000 сегментами.
  • map2 содержит 999999 записей с 999999 сегментами.

И предположим, у нас есть объект "obj1" с hashCode "1234", и мы помещаем этот объект в качестве ключа как в map1, так и в map2 (со значением "xyz").

Требуется ли этобольше времени, чтобы найти значение "obj1" в map2?Будет ли временная сложность все еще O (1) для доступа к obj1 как с map1, так и с map2?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Я думаю, что было бы лучше ответить с кодом и диаграммой.Мы все знаем, что это за функция хеширования (односторонняя).В основном он принимает произвольный ввод и возвращает число (в Java это int, но это не всегда так).И int в Java имеет 32 бита.Это означает, что оно может составлять от -2 147 483 648 до 2 147 483 647.Каждый объект в каждом существующем java-хипе может вычислить свой хеш (используя метод из класса java.util.Object), и он должен находиться в этом интервале.

Теперь давайте предположим, что у нас есть 3 объекта.

21234 = obj1.hashCode();  
623424 = obj2.hashCode();
23124432 = obj3.hasCode();

и мы хотим добавить их в хэш-карту, содержащую 200 сегментов.(это не рабочий код Java, я набрал его здесь)

public class MyHashMap {
    private final Buckets[] buckets = new Buckets[200];

    public boolean add(Object object){
        int resultModulo = object.hashCode() % 200;
        buckets[buckets].add(object);
    } 
}

Теперь для окончательного мира.Для нашего объекта resultModulo будет 34 (21234), 24 (623424), 32 (23124432).И вычисляемое число не будет превышать 200.

Массив выделяется как непрерывный кусок памяти.Просто массив указателей (64-битных), а не реальных объектов.Таким образом, bucktes [] выглядит примерно так

0xB80000xB80020xB80670xC1101 ....
1      2      3      4       .... 200

и поэтому, когда ваш код вызывает bucket [34], bucket [24], bucket [32], то, что аппаратное обеспечение делает так:

  mov eax, bucktes[ecx*19] 
  ; eax now contains the pointer to the
  ; 19 element in the array
  ; this is a one clock instruction

Так вот почему неважно, сколько у вас ведер.

0 голосов
/ 28 ноября 2018

Нахождение сегмента - это O (1) в HashMap, всегда, независимо от емкости (количества сегментов).

Допустим, ваш obj1 имеет хеш-код 1234567.Суть HashMap заключается не в поиске правильного сегмента (как это сделал бы TreeMap), а в том, чтобы вычислить его положение и немедленно получить доступ к сегменту с этим номером.Вот где хэш-код входит в игру.

Вычисление составляет obj.hashCode() % capacity, и полученное число дает индекс в bucketsArray.

  • Длямаленькая хеш-карта, это 1234567 % 1000 = 567, что означает, что соответствующий сегмент равен bucketsArray[567].

  • Для большой это 1234567 % 999999 = 234568, в результате чего bucketsArray[234568].

Время, необходимое для вычисленияделение покоя является постоянным, независимым от значений.Время доступа к массиву с заданным индексом также является постоянным, поэтому оно равно O (1).

Мы говорили только о поиске сегмента.Если корзина содержит несколько записей, линейный поиск завершает доступ к карте хеш-функции, и это O (K), где K - это (среднее? Максимальное?) Количество записей в корзине.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...