1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6

# конспект · шаг 6 из 6

Конспект: цепочки и открытая адресация

выжимка - её можно унести в заметки

Понятия

Метод цепочек (chaining) - каждая ячейка хранит СПИСОК попавших в неё ключей. Вставка O(1) (в начало списка ячейки h(ключ)); поиск/удаление - h(ключ) плюс проход по списку. Поиск ≈ 1 + α. Допускает α > 1, простое удаление, не ломается от переполнения. Плата - память на указатели, разброс по куче (плохая локальность).

Открытая адресация (open addressing) - ключи лежат ПРЯМО в массиве; при коллизии пробируют следующие ячейки. Поиск идёт по цепочке проб до ключа или до ПУСТОЙ ячейки. Поиск ≈ 1/(1 − α), α < 1 обязателен. Отличная локальность памяти.

Пробирование - правило обхода ячеек при коллизии: - линейное h, h+1, h+2, … (страдает кластеризацией); - квадратичное h + i² (гасит первичную кластеризацию, остаётся вторичная); - двойное h₁ + i·h₂(ключ) (шаг задаёт вторая функция, кластеры почти исчезают - лучшее).

Надгробие (tombstone) - пометка «удалено, но не пусто». Нужна, потому что опустошить ячейку нельзя - пустота посреди чужой цепочки проб оборвёт поиск. Поиск идёт сквозь надгробие дальше; надгробия копятся и требуют периодической уборки (рехеш).

Кластеризация - слипание занятых ячеек в сгустки; самоусиливается (большие кластеры притягивают ключи сильнее). Удлиняет пробы даже при умеренном α.

Что унести

Два способа - противоположные компромиссы.

цепочки открытая адресация
где лишние ключи в списке ячейки в других ячейках массива
поиск ≈ 1 + α (мягко) ≈ 1/(1 − α) (взрыв у α=1)
допустимый α любой (даже > 1) строго < 1 (держат ≤ 0.7)
удаление простое через надгробия
память указатели + разброс компактно, всё в массиве
локальность (кеш) плохая (прыжки) отличная (соседние ячейки)

Число проб при заданном α:

α цепочки откр. адр.
0.5 1.5 2.0
0.7 1.7 3.3
0.9 1.9 10
0.99 1.99 100

Правило выбора: до α ≈ 0.7 оба быстры, и открытая адресация ВЫИГРЫВАЕТ по реальному времени за счёт кеша (проба - чтение соседней ячейки, а не прыжок по указателю) - потому её берут быстрые современные dict. Нужна работа под завязку или частые удаления - цепочки (так HashMap в Java, с превращением длинных цепочек в деревья). Асимптотика проб - не единственный критерий: локальность памяти часто решает.

Ловушки джокера

При коллизии положил в соседнюю ячейку, а ищешь только в h(ключ). Не найдёшь. Всё с одним номером - в одном списке (цепочки) или по одной цепочке проб (адресация).

Не сравнил сами КЛЮЧИ при проходе. В одной ячейке/цепочке разные ключи с одним хешем.

Удалил, опустошив ячейку (открытая адресация). Порвал чужую цепочку проб. Нужны надгробия.

Остановился на надгробии как на пустой ячейке. Сквозь надгробие идут ДАЛЬШЕ.

Заполнил открытую адресацию под завязку (α → 1). 1/(1−α) взрывается; вставить некуда, поиск зацикливается.

Выбрал способ по одной асимптотике. При низком α кеш-локальность открытой адресации бьёт «лучшую» формулу цепочек.

Проверь себя

Как цепочки хранят столкнувшиеся ключи и почему поиск O(1 + α)?

Как работает пробирование и почему открытой адресации нужен α < 1?

Зачем нужны надгробия и что будет без них?

Что такое кластеризация и чем её лечат?

При α = 0.9 сколько проб у каждого способа и что это значит для выбора?

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

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