2.3 KiB
2.3 KiB
Задача 10 — хеш-таблица с открытой адресацией (C++)
Свой контейнер, без std::unordered_map. Разрешение коллизий — линейное зондирование
(linear probing), ёмкость — степень двойки, при загрузке > 0.7 таблица перехешируется
вдвое. Индексация — через маску idx & (capacity - 1), а не %.
class HashTable {
public:
explicit HashTable(std::size_t initial_capacity = 16);
void put(int key, int value); // обновляет значение, если ключ уже есть
bool get(int key, int& out) const; // false — ключа нет
bool erase(int key); // false — ключа не было
std::size_t size() const;
std::size_t capacity() const; // степень двойки, >= 16
};
Требования:
put100 000 ключей — суммарно быстрее 2 секунд (в среднем O(1));- ключи с совпадающими младшими битами (например, все кратные 16) обязаны находиться — это проверка зондирования, а не «повезло с хешем»;
- после 100 000 вставок
capacity()растёт (степень двойки, загрузка ≤ 0.7), аsize()честно считает элементы, включая обновления существующих ключей; - удаление должно работать: после
eraseключ не находится, а поиск другого ключа, стоявшего за ним в цепочке зондирования, по-прежнему работает.
Проверка: python3 grade.py 10. Критерий: все ok, сборка без предупреждений,
ASAN/UBSAN чистые.
Разбор после сдачи: почему ёмкость — степень двойки; чем линейное зондирование лучше цепочек по кэшу и хуже по кластеризации; как tombstone-метки спасают поиск после удаления.