Вычислим вероятность, что все дни рождения будут в разные даты. Для этого посчитаем произведение вероятностей того, что день рождение каждого человека не совпадёт ни с чьим другим.
Для первого человека такая вероятность будет равна 1. Для второго человека —
1−3651, так как один день уже занят. Для второго занято будет уже 2 дня. И так далее.
p~(n)=1⋅(1−3651)⋅(1−3652)⋯(1−365n−1)=365n365⋅364⋯(365−n+1)=365n(365−n)!365!.
Нас интересует событие, обратное этому.
p(n)=1−p~(n). Посмотрим на график зависимости вероятности минимум двух совпадений от количества людей:
Если взять 23 человека, вероятность будет 50%.
Значит, что если взять таблицу, в которой 365 значений, и расположить в ней 23 ключа, то уже в этом случае вероятность коллизии будет 50%.
Построить хеш-таблицу, в которой никогда не будет коллизий, — сложно, поэтому нужно уметь бороться с ними.
Коллизия — это ситуация, когда для разных данных функция возвращает одно и то же значение.
Гоша: А что же делать в таком случае?
Тимофей: Существуют разные способы решения этой проблемы. Например, метод цепочек.
Вам хорошо знакома такая структура данных как связный список. Её используют в методе цепочек при разрешении коллизий.
Допустим, нужно добавить ключ:
- Вычисляем значение хеш-функции x от добавляемого ключа.
- Находим H[x] — указатель на список ключей.
- Вставляем элемент в связный список.