Нужна помощь в создании собственного хеш-таблицы - PullRequest
3 голосов
/ 08 февраля 2012

Я изучаю хеш-таблицы, пытаясь понять, как они работают. Я хотел бы сделать довольно простую хеш-таблицу с отдельной цепочкой (используя списки в массиве). У меня есть несколько вопросов:

  1. Предполагая, что ключи могут быть любого типа, я бы потребовал, чтобы пользователь реализовал функцию хеширования, верно? Можно ли этого избежать?

  2. Пользователь также должен указать длину массива, содержащего списки (для коллизий) при инициализации, правильно? Можно ли этого избежать?

Если у вас есть какие-либо другие советы, или, может быть, несколько простых примеров кода на C ++ хэш-таблицы, я был бы благодарен.

Спасибо за вашу помощь.

Ответы [ 3 ]

5 голосов
/ 08 февраля 2012

Как правило, да, вам нужно, чтобы клиент указывал хеш-функцию, поскольку, если вы пишете универсальную хеш-таблицу и работаете с произвольным типом T, вы не можете знать, как ее хешировать таким образом, чтобы семантически значимый. Вы можете сделать это путем параметризации класса как по типу хранимых элементов, так и по хеш-функции. Например:

template <typename T, typename Hash = std::hash<T>>
    class MyHashTable {
    /* ... */
}

Здесь вы можете использовать аргументы по умолчанию с шаблонами, чтобы выбрать хеш-функцию по умолчанию, если пользователь не укажет иное.

Хотя клиент обычно может указывать начальный размер таблицы, это не обязательно. Вы можете сделать обоснованное предположение о количестве сегментов (скажем, сначала использовать 17 сегментов), увеличивая таблицу по мере увеличения коэффициента загрузки. Это похоже, скажем, на то, как работает std::vector: реализация может выбрать размер по умолчанию, но если клиент явно запрашивает предварительно заданный вектор или вызывает reserve, реализация получает подсказку от пользователя. Например, вы можете иметь конструктор вида

template <typename T, typename Hash = std::hash<T>>
    class MyHashTable {
public:
    MyHashTable(unsigned numBuckets = 17);
}

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

Что касается примеров кода, я не уверен, как их предоставить, не отказываясь от множества сложностей, связанных с созданием хеш-таблицы. :-) Если есть определенный фрагмент кода, который вас интересует и у вас проблемы с написанием самостоятельно, не стесняйтесь опубликовать его как отдельный вопрос, чтобы вы могли получить более целенаправленную обратную связь.

Надеюсь, это поможет!

0 голосов
/ 08 февраля 2012

Если вы пытаетесь узнать о хеш-таблицах, я предлагаю вам начать с самых простых из них, которые являются хеш-таблицами с линейным сцеплением

Здесь вы рассматриваете массив указателей фиксированного размера (указатели на тип определенный элементвами), где будут храниться ваши элементы, рассмотрите также наличие некоторых счетчиков, один для отслеживания длины массива и другой для отслеживания количества элементов, добавленных в таблицу до определенного момента

Вы можете использовать макрос для определения функции добавления элементов в хеш-таблицу, например:

 h(k) = k % M  

, где k - индекс (ключ) добавляемого элемента, а M - простое число, представляющееразмер массива указателей (например, 13, 29, 41, 543) и h (k) даст вам позицию, куда будет вставлен элемент.

Причина, по которой вам следует рассмотреть возможность использования фиксированного размерамассив указателей заключается в том, что таким образом вы получаете

 O(n) 

стоимость.

Поэтому, начиная с этой простой функции, вы можете затем изменитьрассмотрим реализацию некоторых более сложных, таких как открытое обращение, линейное зондирование, квадратичное зондирование и двойное хеширование

Что касается запрошенного пользователем ввода относительно количества элементов, я полностью согласен с тем, что templatetypedef сказал ранее

0 голосов
/ 08 февраля 2012

Посмотрите на различные реализации алгоритмов хеширования.Есть много доступных.Вы можете иметь хеш-память переменной, если хотите.Тебе решать.В большинстве алгоритмов хеширования возможны коллизии.Имейте это в виду.

...