Sobes.tech
Назад к вопросам
Junior — Middle
74

Какими методами можно предотвратить или разрешить столкновения при использовании хеш-таблиц?

Ответ от нейросети

sobes.tech AI

Столкновения в хеш-таблицах возникают, когда два разных ключа имеют одинаковое значение хеша. Основные методы предотвращения или разрешения таких столкновений:

  1. Метод цепочек (chaining) — в каждой ячейке хеш-таблицы хранится связный список (или другая структура), куда добавляются все элементы с одинаковым хешем. При поиске перебираются элементы в списке.

  2. Открытая адресация (open addressing) — при коллизии ищется следующая свободная ячейка по определённому правилу (линейное пробирование, квадратичное пробирование, двойное хеширование).

  3. Двойное хеширование — при коллизии вычисляется второй хеш, который используется для поиска следующей ячейки.

  4. Ре-хеширование (rehashing) — при достижении определённой загрузки таблицы создаётся новая таблица большего размера, и все элементы перехешируются.

Пример метода цепочек на Swift:

class HashTable<Key: Hashable, Value> {
    private var buckets: [[(key: Key, value: Value)]]
    private let capacity: Int

    init(capacity: Int = 16) {
        self.capacity = capacity
        self.buckets = Array(repeating: [], count: capacity)
    }

    func hash(_ key: Key) -> Int {
        return abs(key.hashValue) % capacity
    }

    func insert(key: Key, value: Value) {
        let index = hash(key)
        for (i, element) in buckets[index].enumerated() {
            if element.key == key {
                buckets[index][i].value = value
                return
            }
        }
        buckets[index].append((key, value))
    }

    func value(for key: Key) -> Value? {
        let index = hash(key)
        for element in buckets[index] {
            if element.key == key {
                return element.value
            }
        }
        return nil
    }
}