logo

Структура даних хеш-таблиці

Що таке хеш-таблиця?

Хеш-таблиця визначається як структура даних, яка використовується для швидкого вставлення, пошуку та видалення пар ключ-значення. Він діє на концепція хешування , де кожен ключ транслюється хеш-функцією в окремий індекс у масиві. Індекс функціонує як місце зберігання відповідного значення. Простими словами, він відображає ключі зі значенням.

Що таке коефіцієнт навантаження?

Коефіцієнт завантаження хеш-таблиці визначається кількістю елементів, які там зберігаються, відносно розміру таблиці. Таблиця може бути захаращена та мати більший час пошуку та колізій, якщо коефіцієнт завантаження високий. Ідеальний коефіцієнт завантаження можна підтримувати за допомогою хорошої хеш-функції та належного зміни розміру таблиці.



Що таке хеш-функція?

Функція, яка перетворює ключі в індекси масиву, відома як хеш-функція. Ключі мають бути рівномірно розподілені по масиву за допомогою пристойної хеш-функції, щоб зменшити колізії та забезпечити швидку швидкість пошуку.

  • Припущення цілого всесвіту: Припускається, що ключі є цілими числами в певному діапазоні відповідно до припущення про цілочисельний всесвіт. Це дає змогу використовувати основні операції хешування, такі як хешування ділення або множення.
  • Хешування шляхом ділення: Цей простий метод хешування використовує як індекс значення ключа, що залишилося після його ділення на розмір масиву. Коли розмір масиву є простим числом і ключі рівномірно розподілені, він працює добре.
  • Хешування множенням: Ця проста операція хешування множить ключ на константу від 0 до 1 перед тим, як брати дробову частину результату. Після цього індекс визначається множенням дробової складової на розмір масиву. Крім того, він працює ефективно, коли клавіші розкидані однаково.

Вибір хеш-функції :

Вибір відповідної хеш-функції базується на властивостях ключів і передбачуваній функціональності хеш-таблиці. Вирішальним є використання функції, яка рівномірно розподіляє клавіші та зменшує зіткнення.

Критерії, за якими вибирається хеш-функція:



  • Щоб забезпечити мінімальну кількість колізій, хороша хеш-функція повинна рівномірно розподіляти ключі по всій хеш-таблиці. Це означає, що для всіх пар ключів ймовірність хешування двох ключів на одній позиції в таблиці має бути досить постійною.
  • Щоб увімкнути швидке хешування та отримання ключа, хеш-функція має бути ефективною з точки зору обчислень.
  • Має бути важко вивести ключ із його хеш-значення. Як наслідок, спроби вгадати ключ за допомогою хеш-значення мають меншу ймовірність успіху.
  • Хеш-функція має бути достатньо гнучкою, щоб налаштовуватися в міру зміни даних, що хешуються. Наприклад, хеш-функція повинна продовжувати працювати належним чином, якщо хешовані ключі змінюють розмір або формат.

Методи вирішення колізій :

Зіткнення виникають, коли два або більше ключів вказують на той самий індекс масиву. З’єднання в ланцюжок, відкрита адресація та подвійне хешування – це кілька методів вирішення колізій.

  • Відкрита адресація : колізії обробляються шляхом пошуку наступного порожнього місця в таблиці. Якщо перший слот уже зайнятий, хеш-функція застосовується до наступних слотів, поки один не залишиться порожнім. Існують різні способи використання цього підходу, включаючи подвійне хешування, лінійне та квадратичне зондування.
  • Окреме з’єднання : У окремому ланцюжку присутній пов’язаний список об’єктів, які хешуються до кожного слота хеш-таблиці. Два ключі включено до пов’язаного списку, якщо вони хешуються до одного слота. Цей метод досить простий у використанні та може керувати декількома зіткненнями.
  • Хешування Робін Гуда: Щоб зменшити довжину ланцюжка, колізії в хешуванні Робін Гуда вирішуються шляхом вимкнення клавіш. Алгоритм порівнює відстань між слотом і зайнятим слотом двох ключів, якщо новий ключ хешує вже зайнятий слот. Існуючий ключ замінюється новим, якщо він ближче до ідеального слота. Це наближає існуючий ключ до ідеального слота. Цей метод має тенденцію до скорочення колізій і середньої довжини ланцюга.

Динамічне змінення розміру:

Ця функція дозволяє хеш-таблиці розширюватися або звужуватися у відповідь на зміни в кількості елементів, що містяться в таблиці. Це сприяє оптимальному коефіцієнту завантаження та швидкому пошуку.

Реалізації хеш-таблиці

Python, Java, C++ і Ruby – це лише деякі з мов програмування, які підтримують хеш-таблиці. Їх можна використовувати як налаштовану структуру даних на додачу до того, що вони часто включаються до стандартної бібліотеки.



Приклад – підрахунок символів у рядку geeksforgeeks.

У цьому прикладі ми використовуємо техніку хешування для збереження кількості рядків.

C++
#include  using namespace std; int main() {  //initialize a string  string s='geeksforgeeks';    // Using an array to store the count of each alphabet   // by mapping the character to an index value  int arr[26]={0};    //Storing the count  for(int i=0;i
Java
public class CharacterCount {  public static void main(String[] args) {  // Initialize a string  String s = 'geeksforgeeks';  // Using an array to store the count of each alphabet  // by mapping the character to an index value  int[] arr = new int[26];  // Storing the count  for (int i = 0; i < s.length(); i++) {  arr[s.charAt(i) - 'a']++;  }  // Search the count of the character  char ch = 'e';  // Get count  System.out.println('The count of ' + ch + ' is ' + arr[ch - 'a']);  } }>
Python
# Initialize a string s = 'geeksforgeeks' # Using a list to store the count of each alphabet # by mapping the character to an index value arr = [0] * 26 # Storing the count for i in range(len(s)): arr[ord(s[i]) - ord('a')] += 1 # Search the count of the character ch = 'e' # Get count print('The count of ', ch, ' is ', arr[ord(ch) - ord('a')])>
C#
using System; class Program {  static void Main(string[] args) {  //initialize a string  string s = 'geeksforgeeks';  // Using an array to store the count of each alphabet   // by mapping the character to an index value  int[] arr = new int[26];  //Storing the count  for (int i = 0; i < s.Length; i++) {  arr[s[i] - 'a']++;  }  //Search the count of the character  char ch = 'e';  // get count  Console.WriteLine('The count of ' + ch + ' is ' + arr[ch - 'a']);  } }>
Javascript
// Initialize a string const s = 'geeksforgeeks'; // Using an array to store the count of each alphabet // by mapping the character to an index value const arr = Array(26).fill(0); // Storing the count for (let i = 0; i < s.length; i++) {  arr[s.charCodeAt(i) - 'a'.charCodeAt(0)]++; } // Search the count of the character const ch = 'e'; // Get count console.log(`The count of ${ch} is ${arr[ch.charCodeAt(0) - 'a'.charCodeAt(0)]}`);>


Вихід:

The count of e is 4>

Аналіз складності хеш-таблиці:

Для операцій пошуку, вставки та видалення хеш-таблиці мають середню часову складність O(1). Однак у гіршому випадку ці операції можуть вимагати O(n) часу, де n – кількість елементів у таблиці.

Застосування хеш-таблиці:

  • Хеш-таблиці часто використовуються для індексування та пошуку великих обсягів даних. Пошукова система може використовувати хеш-таблицю для зберігання веб-сторінок, які вона проіндексувала.
  • Дані зазвичай кешуються в пам’яті за допомогою хеш-таблиць, що забезпечує швидкий доступ до часто використовуваної інформації.
  • Хеш-функції часто використовуються в криптографії для створення цифрових підписів, перевірки даних і гарантії цілісності даних.
  • Хеш-таблиці можна використовувати для реалізації індексів бази даних, що забезпечує швидкий доступ до даних на основі ключових значень.