33 lines
2.3 KiB
Markdown
33 lines
2.3 KiB
Markdown
# Задача 10 — хеш-таблица с открытой адресацией (C++)
|
||
|
||
Свой контейнер, без `std::unordered_map`. Разрешение коллизий — **линейное зондирование**
|
||
(linear probing), ёмкость — степень двойки, при загрузке > 0.7 таблица **перехешируется**
|
||
вдвое. Индексация — через маску `idx & (capacity - 1)`, а не `%`.
|
||
|
||
```c++
|
||
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
|
||
};
|
||
```
|
||
|
||
Требования:
|
||
- `put` 100 000 ключей — суммарно быстрее 2 секунд (в среднем O(1));
|
||
- ключи с совпадающими младшими битами (например, все кратные 16) обязаны находиться —
|
||
это проверка зондирования, а не «повезло с хешем»;
|
||
- после 100 000 вставок `capacity()` растёт (степень двойки, загрузка ≤ 0.7), а `size()`
|
||
честно считает элементы, включая обновления существующих ключей;
|
||
- удаление должно работать: после `erase` ключ не находится, а поиск другого ключа,
|
||
стоявшего за ним в цепочке зондирования, по-прежнему работает.
|
||
|
||
Проверка: `python3 grade.py 10`. Критерий: все `ok`, сборка без предупреждений,
|
||
ASAN/UBSAN чистые.
|
||
|
||
Разбор после сдачи: почему ёмкость — степень двойки; чем линейное зондирование лучше
|
||
цепочек по кэшу и хуже по кластеризации; как tombstone-метки спасают поиск после удаления.
|