Існує кілька методик, які гарантують, що пошук завжди вимагатиме операцій O (1), навіть у гіршому випадку.
Як я можу визначити, чи може хеш-таблиця мати операції O (1) і, можливо, які методи використовувати для моєї хеш-функції?
Найгірший випадок трапляється, коли якийсь зловмисний зловмисник (Маллорі) навмисно надає вам дані, які Маллорі спеціально вибрав для того, щоб система працювала повільно.
Після того, як ви вибрали якусь конкретну функцію хешу, мабуть, надмірно оптимістично вважати, що Маллорі ніколи не дізнається, яку саме функцію ви вибрали. Після того, як Mallory виявить, яку вибрану хеш-функцію ви дозволите, якщо ви дозволите Mallory видавати багато даних, які потрібно вставити в вашу хеш-таблицю за допомогою цієї хеш-функції, тоді ви приречені: Mallory може внутрішньо швидко створювати мільярди елементів даних, хешувати їх своїми хеш-функція, щоб знайти, які елементи даних можуть зіткнутися, а потім подати вам мільйони тисяч на тисячу елементів, які можуть зіткнутися, що призводить до пошуку, які працюють набагато повільніше, ніж O (1).
Усі методи, які гарантують "O (1) пошук навіть у гіршому випадку", уникають цієї проблеми, зробивши трохи додаткової роботи над кожною вставкою, щоб гарантувати, що в майбутньому кожен можливий пошук може досягти успіху в O (1) час . Зокрема, ми припускаємо (в гіршому випадку), що Меллорі рано чи пізно виявить, яку хеш-функцію ми використовуємо; але він отримує лише можливість вставити декілька даних даних, перш ніж вибрати іншу хеш-функцію - хешування таблиць або інший універсальний хеш - той, який ми спеціально вибираємо таким, щоб усі дані, які ми маємо дотепер, можна було переглянути 2 або 3 зонди - тобто O (1). Оскільки ми вибираємо цю функцію випадковим чином, ми можемо бути досить впевнені, що Меллорі не знатиме, яку функцію ми вибрали на деякий час. Навіть якщо Меллоріодразу дає нам дані про те, що навіть за допомогою цієї нової хеш-функції зіштовхується з попередніми даними, ми можемо вибрати ще одну нову нову хеш-функцію, щоб після повторного перегляду всі попередні дані, які він та всі інші годували нас, тепер можна було переглянути в 2 або 3 зонди в гіршому випадку - тобто, O (1) пошуку в гіршому випадку.
Досить легко випадковим чином вибрати нову хеш-функцію та повторно переробити всю таблицю досить часто, щоб гарантувати, що кожен пошук завжди є O (1). Хоча це гарантує, що кожен пошук завжди є O (1), ці методи під час вставки N-го елемента в хеш-таблицю, яка вже містить елементи N-1, можуть періодично вимагати часу O (N) для цієї вставки. Однак можна спроектувати систему таким чином, що навіть коли Меллорі навмисно надає вам нові дані, які, використовуючи нову хеш-функцію, стикаються з попередніми даними, система може приймати безліч предметів від Маллорі та інших, перш ніж їй потрібно зробити повне відновлення (N). Прийоми таблиці хешу, які вибирають нову функцію і повторно переробляють, щоб гарантувати пошук (1) пошуку, навіть у гіршому випадку, включають:
- хешування зозулі гарантує, що пошук кожної клавіші досягає щонайменше 2 хеш-обчислень та 2 пошукових таблиць.
- хеш-пам'ять hopscotch гарантує, що пошук кожного ключа буде успішним після огляду послідовних записів у таблиці невеликої кількості H (можливо H = 32).
- динамічне ідеальне хешуваннявання - папір Дітцфельбінгера 1994 року - це перший, який я прочитав, який зазначив, що, хоч і переробляє "часто", щоб гарантувати, що кожен пошук ключів завжди досягає 2 хеш-обчислень та 2 пошукових запитів, це можливо робити повну повторну операцію так рідко, що навіть незважаючи на те, що кожна повна повторна операція використовує O (n) час, очікувана середня вартість вставки та видалення амортизується O (1).
Структури даних / Хеш-таблиці