Как Swift обрабатывает коллизии в словаре (Dictionary)?

«Как Swift обрабатывает коллизии в словаре (Dictionary)?» — вопрос из категории Алгоритмы и структуры данных, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Swift использует метод цепочек (separate chaining) для разрешения коллизий в Dictionary.

Механизм работы:

  1. Каждая "корзина" (bucket) в хеш-таблице содержит связанный список (или массив) элементов.
  2. При добавлении элемента с ключом, чей хеш совпадает с хешем существующего ключа в той же корзине, новый элемент добавляется в этот список.
  3. При поиске по ключу система:
    • Вычисляет хеш ключа.
    • Находит соответствующую корзину.
    • Последовательно проверяет (через сравнение ==) все ключи в списке этой корзины, чтобы найти точное совпадение.

Пример и последствия:

var dictionary = [Int: String]()
// Предположим, что ключи 1 и 101 дают одинаковый хеш и попадают в одну корзину.
dictionary[1] = "One"
dictionary[101] = "One Hundred One" // Коллизия: элемент добавляется в список внутри корзины.

let value = dictionary[101] // Поиск: вычисляется хеш 101, находится корзина, в её списке находится ключ 101.

Важно:

  • В худшем случае (все ключи в одной корзине) сложность операций падает с O(1) до O(n).
  • Swift автоматически выполняет ресайзинг (rehashing) таблицы при высокой нагрузке (большом коэффициенте заполнения), чтобы уменьшить количество коллизий и сохранить производительность.
  • Качество встроенной хеш-функции (hash(into:)) минимизирует коллизии на практике.