Мне нужно реализовать хэш-таблицу массива, которая работает без начальной инициализации массива в значение null. Есть какие-нибудь подсказки, как это сделать?

#java #algorithm #data-structures #hashtable

#java #алгоритм #структуры данных #хеш-таблица

Вопрос:

Итак, вот актуальный вопрос (это для домашнего задания):

Хеш-таблица — это структура данных, которая позволяет получать доступ и манипулировать датой в постоянное время (O (1)). Массив хэш-таблицы должен быть инициализирован в null во время создания хэш-таблицы, чтобы идентифицировать пустые ячейки. В большинстве случаев временные затраты огромны, особенно учитывая, что большинство ячеек никогда не будут прочитаны. Мы просим вас реализовать хэш-таблицу, которая позволяет обойти эту проблему ценой более тяжелой вставки, но при этом с постоянным временем. Для целей этого домашнего задания и для упрощения вашей работы мы предполагаем, что вы не можете удалять элементы в этой хеш-таблице.

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

Вот несколько фактов, которые следует учитывать:

  • В хеш-таблице, содержащей целые числа, таблица содержит числовые значения (но они не имеют никакого смысла).

  • В стеке вы не можете получить доступ к элементам поверх самого высокого элемента, но вы точно знаете, что все значения действительны. Кроме того, вы знаете индекс самого высокого элемента.

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

Кроме того, вот интерфейс, который мне нужно реализовать для этого домашнего задания:

 public interface NoInitHashTable<E>
{
    public void insert(E e);
    public boolean contains(E e);

    public void rehash();
    public int nextPrime(int n);
    public boolean isPrime(int n);
}
  

Я уже реализовал nextPrime и isPrime (я не думаю, что они отличаются от обычной хеш-таблицы). Три других, которые мне нужно выяснить.

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

tl; dr Мне нужно реализовать хэш-таблицу массива, которая работает без инициализации массива в null в начале. Вставка должна выполняться в постоянное время. Мне нужно только знать основной принцип того, как это сделать.

Комментарии:

1. Интересная задача. Я предполагаю, что профессор дал вам еще несколько советов во время недавних лекций — вам следует вспомнить, что он сказал на последних двух занятиях, чтобы посмотреть, есть ли какие-то дополнительные подсказки.

2. Подсказка: нигде он не определяет интерфейс для установки размера хэш-таблицы.

3. Чтобы получить временную сложность O (1), вам нужен идеальный алгоритм хеширования. т. Е. Никаких столкновений. Это редко бывает в реальных приложениях. 😉

4. @PeterLawrey, O(1) не означает отсутствия столкновений. Если количество столкновений ограничено, у вас все равно может быть O (1) . И обычные реализации хеш-таблиц — O (1), предполагая, что у вас есть разумное распределение хеш-кодов.

Ответ №1:

Я думаю, что видел это в книге как упражнение с ответом в конце, но я не могу вспомнить, в какой книге или где. Как правило, это относится к вопросу о том, почему мы обычно концентрируемся на времени, которое занимает программа, а не на пространстве — программе, которая работает эффективно во времени, не должно требоваться огромное количество места.

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

 // each cell here is for a cell at the same offset in the
// hash table
int numValidWhenFirstSetValid[SIZE];
int numValidSoFar = 0; // initialise only this
// Only cells 0..numValidSoFar-1 here are valid.
int validOffsetsInOrderSeen[SIZE];

boolean isValid(int offsetInArray)
{
  int supposedWhenFirstValid =
   numValidWhenFirstSetValid[offsetInArray]
  if supposedWhenFirstValid >= numValidSoFar)
  {
    return false;
  }
  if supposedWhenFirstValid < 0)
  {
    return false;
  }
  if (validOffsetsInOrderSeen[supposedWhenFirstValid] !=
    offsetInArray)
  {
    return false;
 }
 return true;
}
  

Редактировать — это упражнение 24 в разделе 2.2.6 Knuth Vol. 1. Предоставленный ответ ссылается на упражнение 2.12 «Проектирование и анализ компьютерных программ» Ахо, Хопкрафта и Ульмана. Вы можете избежать любых обвинений в плейгаризме в своем ответе, сославшись на источник заданного вам вопроса 🙂

Комментарии:

1. Я не брал это из этой книги: это был вопрос, заданный для домашнего задания, и он ни на что не ссылался.

2. Спасибо за пример. Я не совсем понимаю, что представляет переменная. Что такое numValidWhenFirstSetValid и suppowedWhenFirstValid ? Спасибо

3. Предположим, что вы заполняете хэш-слоты 3, 5, 2 в таком порядке, поэтому validOffsetsInOrderSeen[] = {3, 5, 2}, numValidWhenFirstSetValid[3] = 0, numValidWhenFirstSetValid[5] = 1, numValidWhenFirstSetValid[2] = 2. numValidWhenFirstSetValid[k] — количество допустимых слотоввидно до сих пор, когда заполнен слот k. Вы знаете, что validOffsetsInOrderSeen[0..numValidSoFar] перечисляет заполненные слоты, поэтому, чтобы проверить, что слот k был заполнен, вы устанавливаете supposedWhenFirstValid = numValidWhenFirstSetValid[k] . Если слот k пуст, это может выглядеть правдоподобно, поэтому вы проверяете validOffsetsInOrderSeen[предположениеwhenfirstvalid] == k .

Ответ №2:

Пометьте каждый элемент в хэш-таблице некоторым цветом (1, 2, …)

Например, текущий цвет:

 int curColor = 0;
  

Когда вы помещаете элемент в хэш-таблицу, свяжите с ним текущий color ( curColor )

Если вам нужно выполнить поиск, отфильтруйте элементы, которые не имеют одинакового цвета ( element.color == curColor )

Если вам нужно очистить хэш-таблицу, просто увеличьте текущий color ( curColor )

Комментарии:

1. Разве это не затруднит поиск O (1)?

2. Среднее время поиска для хеш-таблицы равно o (n). Но когда количество элементов становится больше размера хеш-таблицы, время поиска будет увеличено. Вы можете очистить всю хеш-таблицу, если количество элементов (старых и текущих) слишком велико

3. Извините, я имел в виду O (n) . Я думаю, что ваше решение сделало бы O (n) . Но требование состоит в том, чтобы сделать его O(1) . Хэш-таблицам обычно удается этого добиться.

4. @svick, Упс, я допустил ошибку в своем комментарии.. Время поиска равно O (1), потому что существует простая хеш-таблица со средним временем поиска O (1)