SlideShare a Scribd company logo
Лекция 6
Хеш-таблицы
Курносов Михаил Георгиевич
к.т.н. доцент Кафедры вычислительных систем
Сибирский государственный университет
телекоммуникаций и информатики
http://www.mkurnosov.net/teaching
АТД “Словарь” (Dictionary)
2
 Словарь (ассоциативный массив, associative array, map,
dictionary) – структура (контейнер) данных для хранения
пар вида “ключ – значение” (key – value)
 Реализации словарей отличаются вычислительной
сложностью операций добавления (Add), поиска (Lookup)
и удаления элементов (Delete)
 Наибольшее распространение получили следующие
реализации:
1. Деревья поиска (Search trees)
2. Хэш-таблицы (Hash tables)
3. Связные списки
4. Массивы
Хеш-таблицы (Hash tables)
3
 Хеш-таблица (Hash table) – это структура данных
для хранения пар “ключ – значение”
 Доступ к элементам осуществляется по ключу (key)
 Ключи могут быть строками, числами, указателями
 Хеш-таблицы позволяют в среднем за время О(1)
выполнять добавление, поиски и удаление элементов
Основная идея (мотивация)
4
 Чем хороши статические массивы int v[100]?
 Очень быстрый (за O(1)) доступ к элементу массива по его
ключу: v[17] = 45
 Ограничение – ключи (индексы) это целые числа
 Можно ли как-то использовать типы float, double,
строки (char []) в качестве индексов в массиве?
 Пример: массив анкет пользователей Twitter (словарь),
ключ – login, значение – анкета (профиль с данными
пользователя)
 Массив структур:
struct twitter_user users[MAX_USERS];
Хеш-таблицы (Hash tables)
5
Ключ
(Key)
Value:
160
“Антилопа Гну”
Хеш-таблица
(Hash table)
Хеш-функция
(Hash function)
hash(key) -> int
0
1
2
…
h – 1
 Хеш-функция – отображает (преобразует)
ключ (key) в номер элемента (index) массива
(в целое число от 0 до h – 1)
 Время вычисления хеш-функции зависит
от длины ключа и не зависит от количества
элементов в массиве
 Ячейки массива называются buckets, slots
index
Хеш-таблицы (Hash tables)
6
Хеш-таблица
(Hash table)
0
1
2
…
h – 1
 На практике, обычно известна информация
о диапазоне значений ключей
 На основе этого выбирается размер h хеш-таблицы
и выбирается хеш-функция
 Коэффициент  заполнения хеш-таблицы
(load factor, fill factor) – отношение числа n
хранимых элементов в хеш-таблицы к размеру h
массива (среднее число элементов на одну ячейку)
α =
𝑛
ℎ
 Пример: h = 128, в хеш-таблицу добавили 50
элементов,тогда  = 50 / 128  0.39
 От этого коэффициента зависит среднее время
выполнения операций добавления, поиска
и удаления элементов
7
Хеш-функции (Hash function)
 Хеш-функция (Hash function) – это функция преобразующая
значения ключа (например: строки, числа, файла) в целое число
 Значение возвращаемое хеш-функцией называется хеш-кодом
(hash code), контрольной суммой (hash sum) или хешем (hash)
#define HASH_MUL 31
#define HASH_SIZE 128
// Хеш-функция для строк [KP, “Practice of Programming”]
unsigned int hash(char *s)
{
unsigned int h = 0;
char *p;
for (p = s; *p != '0'; p++)
h = h * HASH_MUL + (unsigned int)*p;
return h % HASH_SIZE;
} Thash = O(|s|)
Хеш-функции (Hash function)
 Хеш-функция (Hash function) – это функция преобразующая
значения ключа (например: строки, числа, файла) в целое число
 Значение возвращаемое хеш-функцией называется хеш-кодом
(hash code), контрольной суммой (hash sum) или хешем (hash)
#define HASH_MUL 31
#define HASH_SIZE 128
int main()
{
unsigned int h = hash(“ivanov”);
}
8
i v a n o v
105 118 97 110 111 118
Хеш-функции (Hash function)
#define HASH_MUL 31
#define HASH_SIZE 128
unsigned int hash(char *s) {
unsigned int h = 0;
char *p;
for (p = s; *p != '0'; p++)
h = h * HASH_MUL + (unsigned int)*p;
return h % HASH_SIZE;
}
9
h = 0 * HASH_MUL + 105
h = 105 * HASH_MUL + 118
h = 3373 * HASH_MUL + 97
h = 104660 * HASH_MUL + 110
h = 3244570 * HASH_MUL + 111
h = 100581781 * HASH_MUL + 118
return 3118035329 % HASH_SIZE // hash(“ivanov”) = 1
i v a n o v
105 118 97 110 111 118
Понятие коллизии (Collision)
10
 Коллизия (Collision) – это совпадение значений хеш-функции
для двух разных ключей
Keys HashesHash function
Жираф
Слон
Муха Цеце
Волк
127
...
05
04
03
02
01
00
Collision!
hash(“Волк”) = 2 hash(“Жираф”) = 2
Существуют хеш-функции без коллизий –
совершенные хеш-функции (perfect hash function)
Разрешение коллизий (Collision resolution)
11
Метод цепочек (Chaining) – закрытая адресация
Элементы с одинаковым значением хеш-функции объединяются в
связный список. Указатель на список хранится в советующей ячейке хеш-
таблицы.
 При коллизии элемент добавляется в начало списка.
 Поиск и удаление элемента требуют просмотра всего списка.
Keys HashesHash function
Жираф
Слон
Муха Цеце
Волк
127
...
05
04
03
02
01
00
Муха Цеце NULL
Слон NULL
Жираф Волк
NULL
Разрешение коллизий (Collision resolution)
12
Открытая адресация (Open addressing)
В каждой ячейке хеш-таблицы хранится не указатель на связный
список, а один элемент (ключ, значение)
Если ячейка с индексом hash(key) занята, то осуществляется поиск
свободной ячейки в следующих позициях таблицы Hash Элемент
0 B
1
2
3 A
4 C
5 D
6
7
Линейное хеширование (linear probing) – проверяются
позиции:
hash(key) + 1, hash(key) + 2, …, (hash(key) + i) mod h, …
Если свободных ячеек нет, то таблица заполнена
Пример:
 hash(D) = 3, но ячейка с иднексом 3 занята.
 Присматриваем ячейки: 4 – занята, 5 – свободна.
Требования к хеш-функциям
13
 Быстрое вычисление хэш-кода по значению ключа
 Сложность вычисления хэш-кода не должна зависеть
от количества n элементов в хеш-таблице
 Детерминированность – для заданного значения ключа
хэш-функция всегда должна возвращать одно и то же
значение
unsigned int hash(char *s) {
unsigned int h = 0;
char *p;
for (p = s; *p != '0'; p++)
h = h * HASH_MUL + (unsigned int)*p;
return h % HASH_SIZE;
}
Требования к хеш-функциям
14
 Равномерность (uniform distribution) –
хеш-функция должна равномерно заполнять
индексы массива возвращаемыми номерами
 Желательно, чтобы все хэш-коды формировались с
одинаковой равномерной распределенной вероятностью
Hash Элемент
0 C, F, G
1
2
3
4 B, E
5
6 A, D, H
7
A
B
C
D
E
F
G
H
Неравномерное
распределение
Требования к хеш-функциям
15
 Равномерность (uniform distribution) –
хеш-функция должна равномерно заполнять
индексы массива возвращаемыми номерами
 Желательно, чтобы все хэш-коды формировались с
одинаковой равномерной распределенной вероятностью
Hash Элемент
0 C
1 A
2 D
3 H
4 B
5 G
6 E
7 F
A
B
C
D
E
F
G
H
Равномерное
распределение
Эффективность хеш-таблиц
16
 Хеш-таблица требует предварительной инициализации
ячеек значениями NULL – трудоемкость O(h)
Операция
Вычислительная
сложность
в среднем случае
Вычислительная
сложность
в худшем случае
Add(key, value) O(1) O(1)
Lookup(key) O(1 + n/h) O(n)
Delete(key) O(1 + n/h) O(n)
Min() O(n + h) O(n + h)
Max() O(n + h) O(n + h)
Пример хэш-функции для строк
17
unsigned int ELFHash(char *key, unsigned int mod)
{
unsigned int h = 0, g;
while (*key) {
h = (h << 4) + *key++;
g = h & 0xf0000000L;
if (g)
h ^= g >> 24;
h &= ~g;
}
return h % mod;
}
 Используются только поразрядные операции
(для эффективности)
Jenkins hash functions
18
uint32_t jenkins_hash(char *key, size_t len)
{
uint32_t hash, i;
for (hash = i = 0; i < len; ++i) {
hash += key[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
Пример хэш-функции для чисел
19
 Ключи: размер файла – число.
 Значение, хранимое в словаре: название файла.
 Требуется разработать хеш-функцию
hash(filesize)  [0..1023]
function hash(int filesize)
return filesize mod 1024
end function
Пример хэш-функции для строк
20
hash 𝑠 =
𝑖=0
𝐿−1
ℎ 𝐿−(𝑖+1) ∙ 𝑠 𝑖 =
= 𝑠[0]ℎ 𝐿−1 + 𝑠[1]ℎ 𝐿−2 + ⋯ + 𝑠 𝐿 − 2 ℎ + 𝑠 𝐿 − 1 ,
где s – ключ (строка), L – длина строки, s[i] – код символа i
Хеш-таблицы (Hash table)
21
 Длину h хеш-таблицы выбирают как простое число
 Для такой таблицы модульная хеш-функция дает
равномерное распределение значений ключей
hash(key) = key mod h
Хеш-таблицы vs. Бинарное дерево поиска
22
Операция
Hash table
(unordered map)
Binary search tree
(ordered map)
Add(key, value) O(m) O(nm)
Lookup(key) O(m + nm) O(nm)
Delete(key) O(m + nm) O(nm)
Min() O(m(n + h)) O(n)
Max() O(m(n + h)) O(n)
 Эффективность реализации словаря хеш-таблицей
(метод цепочек) и бинарным деревом поиска
 Ключ – это строка из m символов
 Оценка сложности для худшего случая (worst case)
Хеш-таблицы vs. Бинарное дерево поиска
23
Операция
Hash table
(unordered map)
Binary search tree
(ordered map)
Add(key, value) O(m) O(mlogn)
Lookup(key) O(m + mn/h) O(mlogn)
Delete(key) O(m + mn/h) O(mlogn)
Min() O(m(n + h)) O(logn)
Max() O(m(n + h)) O(logn)
 Эффективность реализации словаря хеш-таблицей
(метод цепочек) и бинарным деревом поиска
 Ключ – это строка из m символов
 Оценка сложности для среднего случая (average case)
Реализация хеш-таблицы
24
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASHTAB_SIZE 71
#define HASHTAB_MUL 31
struct listnode {
char *key;
int value;
struct listnode *next;
};
struct listnode *hashtab[HASHTAB_SIZE];
Хеш-функция
25
unsigned int hashtab_hash(char *key)
{
unsigned int h = 0;
char *p;
for (p = key; *p != '0'; p++) {
h = h * HASHTAB_MUL + (unsigned int)*p;
}
return h % HASHTAB_SIZE;
} THash = O(|key|)
Инициализация хеш-таблицы
26
void hashtab_init(struct listnode **hashtab)
{
int i;
for (i = 0; i < HASHTAB_SIZE; i++) {
hashtab[i] = NULL;
}
}
TInit = O(h)
27
Добавление элемента в хеш-таблицу
void hashtab_add(struct listnode **hashtab,
char *key, int value)
{
struct listnode *node;
int index = hashtab_hash(key);
// Вставка в начало списка
node = malloc(sizeof(*node));
if (node != NULL) {
node->key = key;
node->value = value;
node->next = hashtab[index];
hashtab[index] = node;
}
}
TAdd = THash + O(1) = O(1)
28
Поиск элемента
struct listnode *hashtab_lookup(
struct listnode **hashtab,
char *key)
{
int index;
struct listnode *node;
index = hashtab_hash(key);
for (node = hashtab[index];
node != NULL; node = node->next)
{
if (strcmp(node->key, key) == 0)
return node;
}
return NULL;
}
TLookup = THash + O(n) = O(n)
Поиск элемента
29
int main()
{
struct listnode *node;
hashtab_init(hashtab);
hashtab_add(hashtab, "Tigr", 190);
hashtab_add(hashtab, "Slon", 2300);
hashtab_add(hashtab, "Volk", 60);
node = hashtab_lookup(hashtab, "Slon");
printf("Node: %s, %dn",
node->key, node->value);
return 0;
}
Удаление элемента
void hashtab_delete(struct listnode **hashtab, char *key)
{
int index;
struct listnode *p, *prev = NULL;
index = hashtab_hash(key);
for (p = hashtab[index]; p != NULL; p = p->next) {
if (strcmp(p->key, key) == 0) {
if (prev == NULL
hashtab[index] = p->next;
else
prev->next = p->next;
free(p);
return;
}
prev = p;
}
}
30
TDelete = THash + O(n) = O(n)
Удаление элемента
31
int main()
{
struct listnode *node;
/* ... */
hashtab_delete(hashtab, "Slon");
node = hashtab_lookup(hashtab, "Slon");
if (node != NULL) {
printf("Node: %s, %dn",
node->key, node->value);
} else {
printf("Key 'Slon' not foundn");
}
return 0;
}
Домашнее чтение
32
 Прочитать в [Sedgewick2001, С. 575] про хеш-функции для
вещественных чисел
 Прочитать в “Практике программирования” [KP]
информацию о хеш-таблицах
 Прочитать “Глава 11. Хеш-таблицы” [CLRS, С. 282]
 Perfect hash function (Совершенная хеш-функция)

More Related Content

What's hot

Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle TreesModern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
Lorenzo Alberton
 
Concept of hashing
Concept of hashingConcept of hashing
Concept of hashing
Rafi Dar
 
Skip List
Skip ListSkip List
Skip List
Paulo Victor
 
Linear Search & Binary Search
Linear Search & Binary SearchLinear Search & Binary Search
Linear Search & Binary Search
Reem Alattas
 
Introduction to elasticsearch
Introduction to elasticsearchIntroduction to elasticsearch
Introduction to elasticsearch
hypto
 
Auditing System Password Using L0phtcrack
Auditing System Password Using L0phtcrackAuditing System Password Using L0phtcrack
Auditing System Password Using L0phtcrack
Vishal Kumar
 
Hashing Part Two: Static Perfect Hashing
Hashing Part Two: Static Perfect HashingHashing Part Two: Static Perfect Hashing
Hashing Part Two: Static Perfect Hashing
Benjamin Sach
 
08 Hash Tables
08 Hash Tables08 Hash Tables
08 Hash Tables
Andres Mendez-Vazquez
 
Python list
Python listPython list
Python list
ArchanaBhumkar
 
linear probing
linear probinglinear probing
linear probing
rajshreemuthiah
 

What's hot (10)

Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle TreesModern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
Modern Algorithms and Data Structures - 1. Bloom Filters, Merkle Trees
 
Concept of hashing
Concept of hashingConcept of hashing
Concept of hashing
 
Skip List
Skip ListSkip List
Skip List
 
Linear Search & Binary Search
Linear Search & Binary SearchLinear Search & Binary Search
Linear Search & Binary Search
 
Introduction to elasticsearch
Introduction to elasticsearchIntroduction to elasticsearch
Introduction to elasticsearch
 
Auditing System Password Using L0phtcrack
Auditing System Password Using L0phtcrackAuditing System Password Using L0phtcrack
Auditing System Password Using L0phtcrack
 
Hashing Part Two: Static Perfect Hashing
Hashing Part Two: Static Perfect HashingHashing Part Two: Static Perfect Hashing
Hashing Part Two: Static Perfect Hashing
 
08 Hash Tables
08 Hash Tables08 Hash Tables
08 Hash Tables
 
Python list
Python listPython list
Python list
 
linear probing
linear probinglinear probing
linear probing
 

Viewers also liked

Лекция 6: Словари. Хеш-таблицы
Лекция 6: Словари. Хеш-таблицыЛекция 6: Словари. Хеш-таблицы
Лекция 6: Словари. Хеш-таблицыMikhail Kurnosov
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Mikhail Kurnosov
 
Лекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиЛекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимости
Mikhail Kurnosov
 
Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)
Mikhail Kurnosov
 
Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)
Mikhail Kurnosov
 
Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)
Mikhail Kurnosov
 
Лекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмов
Mikhail Kurnosov
 
Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)
Mikhail Kurnosov
 
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Mikhail Kurnosov
 
Векторизация кода (семинар 2)
Векторизация кода (семинар 2)Векторизация кода (семинар 2)
Векторизация кода (семинар 2)
Mikhail Kurnosov
 

Viewers also liked (10)

Лекция 6: Словари. Хеш-таблицы
Лекция 6: Словари. Хеш-таблицыЛекция 6: Словари. Хеш-таблицы
Лекция 6: Словари. Хеш-таблицы
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
 
Лекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиЛекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимости
 
Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)
 
Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)
 
Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)
 
Лекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмов
 
Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)
 
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
 
Векторизация кода (семинар 2)
Векторизация кода (семинар 2)Векторизация кода (семинар 2)
Векторизация кода (семинар 2)
 

Similar to Лекция 6: Хеш-таблицы

Лекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицыЛекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицы
Mikhail Kurnosov
 
Лекция 4 Элементарные структуры данных часть 2
Лекция 4 Элементарные структуры данных часть 2Лекция 4 Элементарные структуры данных часть 2
Лекция 4 Элементарные структуры данных часть 2
simple_people
 
Java. Интерфейс Map - ассоциативные массивы.
Java. Интерфейс Map - ассоциативные массивы.Java. Интерфейс Map - ассоциативные массивы.
Java. Интерфейс Map - ассоциативные массивы.
Unguryan Vitaliy
 
Хэши в ruby
Хэши в rubyХэши в ruby
Хэши в ruby
Evgeny Smirnov
 
Алгоритмы и структуры данных осень 2013 лекция 7
Алгоритмы и структуры данных осень 2013 лекция 7Алгоритмы и структуры данных осень 2013 лекция 7
Алгоритмы и структуры данных осень 2013 лекция 7Technopark
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Mikhail Kurnosov
 
Big Data - первые шаги
Big Data - первые шагиBig Data - первые шаги
Big Data - первые шагиAnton Gorokhov
 
Лекция №8. Поиск. Хэширование. Предмет "Структуры и алгоритмы обработки данных"
Лекция №8. Поиск. Хэширование. Предмет "Структуры и алгоритмы обработки данных"Лекция №8. Поиск. Хэширование. Предмет "Структуры и алгоритмы обработки данных"
Лекция №8. Поиск. Хэширование. Предмет "Структуры и алгоритмы обработки данных"Nikolay Grebenshikov
 
Лекция 3 Элементарные структуры данных Часть 1
Лекция 3 Элементарные структуры данных Часть 1Лекция 3 Элементарные структуры данных Часть 1
Лекция 3 Элементарные структуры данных Часть 1
simple_people
 
Базы данных. Hash & Cache
Базы данных. Hash & CacheБазы данных. Hash & Cache
Базы данных. Hash & Cache
Vadim Tsesko
 
Егор Львовский — «Кеширование на клиенте и сервере»
Егор Львовский — «Кеширование на клиенте и сервере»Егор Львовский — «Кеширование на клиенте и сервере»
Егор Львовский — «Кеширование на клиенте и сервере»Yandex
 
Коллекции в Java
Коллекции в JavaКоллекции в Java
Коллекции в Java
metaform
 

Similar to Лекция 6: Хеш-таблицы (12)

Лекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицыЛекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицы
 
Лекция 4 Элементарные структуры данных часть 2
Лекция 4 Элементарные структуры данных часть 2Лекция 4 Элементарные структуры данных часть 2
Лекция 4 Элементарные структуры данных часть 2
 
Java. Интерфейс Map - ассоциативные массивы.
Java. Интерфейс Map - ассоциативные массивы.Java. Интерфейс Map - ассоциативные массивы.
Java. Интерфейс Map - ассоциативные массивы.
 
Хэши в ruby
Хэши в rubyХэши в ruby
Хэши в ruby
 
Алгоритмы и структуры данных осень 2013 лекция 7
Алгоритмы и структуры данных осень 2013 лекция 7Алгоритмы и структуры данных осень 2013 лекция 7
Алгоритмы и структуры данных осень 2013 лекция 7
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
 
Big Data - первые шаги
Big Data - первые шагиBig Data - первые шаги
Big Data - первые шаги
 
Лекция №8. Поиск. Хэширование. Предмет "Структуры и алгоритмы обработки данных"
Лекция №8. Поиск. Хэширование. Предмет "Структуры и алгоритмы обработки данных"Лекция №8. Поиск. Хэширование. Предмет "Структуры и алгоритмы обработки данных"
Лекция №8. Поиск. Хэширование. Предмет "Структуры и алгоритмы обработки данных"
 
Лекция 3 Элементарные структуры данных Часть 1
Лекция 3 Элементарные структуры данных Часть 1Лекция 3 Элементарные структуры данных Часть 1
Лекция 3 Элементарные структуры данных Часть 1
 
Базы данных. Hash & Cache
Базы данных. Hash & CacheБазы данных. Hash & Cache
Базы данных. Hash & Cache
 
Егор Львовский — «Кеширование на клиенте и сервере»
Егор Львовский — «Кеширование на клиенте и сервере»Егор Львовский — «Кеширование на клиенте и сервере»
Егор Львовский — «Кеширование на клиенте и сервере»
 
Коллекции в Java
Коллекции в JavaКоллекции в Java
Коллекции в Java
 

More from Mikhail Kurnosov

Векторизация кода (семинар 3)
Векторизация кода (семинар 3)Векторизация кода (семинар 3)
Векторизация кода (семинар 3)
Mikhail Kurnosov
 
Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)
Mikhail Kurnosov
 
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Mikhail Kurnosov
 
Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)
Mikhail Kurnosov
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
Mikhail Kurnosov
 
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Mikhail Kurnosov
 
Лекция 5. B-деревья (B-trees, k-way merge sort)
Лекция 5. B-деревья (B-trees, k-way merge sort)Лекция 5. B-деревья (B-trees, k-way merge sort)
Лекция 5. B-деревья (B-trees, k-way merge sort)
Mikhail Kurnosov
 
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Mikhail Kurnosov
 
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
Mikhail Kurnosov
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Mikhail Kurnosov
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)
Mikhail Kurnosov
 
Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)
Mikhail Kurnosov
 
Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)
Mikhail Kurnosov
 
Лекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графеЛекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графе
Mikhail Kurnosov
 
Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)
Mikhail Kurnosov
 
Лекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовЛекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графов
Mikhail Kurnosov
 
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Mikhail Kurnosov
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Mikhail Kurnosov
 
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Mikhail Kurnosov
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Mikhail Kurnosov
 

More from Mikhail Kurnosov (20)

Векторизация кода (семинар 3)
Векторизация кода (семинар 3)Векторизация кода (семинар 3)
Векторизация кода (семинар 3)
 
Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)
 
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
 
Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
 
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
 
Лекция 5. B-деревья (B-trees, k-way merge sort)
Лекция 5. B-деревья (B-trees, k-way merge sort)Лекция 5. B-деревья (B-trees, k-way merge sort)
Лекция 5. B-деревья (B-trees, k-way merge sort)
 
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
 
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)
 
Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)
 
Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)
 
Лекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графеЛекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графе
 
Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)
 
Лекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовЛекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графов
 
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировка
 
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
 

Лекция 6: Хеш-таблицы

  • 1. Лекция 6 Хеш-таблицы Курносов Михаил Георгиевич к.т.н. доцент Кафедры вычислительных систем Сибирский государственный университет телекоммуникаций и информатики http://www.mkurnosov.net/teaching
  • 2. АТД “Словарь” (Dictionary) 2  Словарь (ассоциативный массив, associative array, map, dictionary) – структура (контейнер) данных для хранения пар вида “ключ – значение” (key – value)  Реализации словарей отличаются вычислительной сложностью операций добавления (Add), поиска (Lookup) и удаления элементов (Delete)  Наибольшее распространение получили следующие реализации: 1. Деревья поиска (Search trees) 2. Хэш-таблицы (Hash tables) 3. Связные списки 4. Массивы
  • 3. Хеш-таблицы (Hash tables) 3  Хеш-таблица (Hash table) – это структура данных для хранения пар “ключ – значение”  Доступ к элементам осуществляется по ключу (key)  Ключи могут быть строками, числами, указателями  Хеш-таблицы позволяют в среднем за время О(1) выполнять добавление, поиски и удаление элементов
  • 4. Основная идея (мотивация) 4  Чем хороши статические массивы int v[100]?  Очень быстрый (за O(1)) доступ к элементу массива по его ключу: v[17] = 45  Ограничение – ключи (индексы) это целые числа  Можно ли как-то использовать типы float, double, строки (char []) в качестве индексов в массиве?  Пример: массив анкет пользователей Twitter (словарь), ключ – login, значение – анкета (профиль с данными пользователя)  Массив структур: struct twitter_user users[MAX_USERS];
  • 5. Хеш-таблицы (Hash tables) 5 Ключ (Key) Value: 160 “Антилопа Гну” Хеш-таблица (Hash table) Хеш-функция (Hash function) hash(key) -> int 0 1 2 … h – 1  Хеш-функция – отображает (преобразует) ключ (key) в номер элемента (index) массива (в целое число от 0 до h – 1)  Время вычисления хеш-функции зависит от длины ключа и не зависит от количества элементов в массиве  Ячейки массива называются buckets, slots index
  • 6. Хеш-таблицы (Hash tables) 6 Хеш-таблица (Hash table) 0 1 2 … h – 1  На практике, обычно известна информация о диапазоне значений ключей  На основе этого выбирается размер h хеш-таблицы и выбирается хеш-функция  Коэффициент  заполнения хеш-таблицы (load factor, fill factor) – отношение числа n хранимых элементов в хеш-таблицы к размеру h массива (среднее число элементов на одну ячейку) α = 𝑛 ℎ  Пример: h = 128, в хеш-таблицу добавили 50 элементов,тогда  = 50 / 128  0.39  От этого коэффициента зависит среднее время выполнения операций добавления, поиска и удаления элементов
  • 7. 7 Хеш-функции (Hash function)  Хеш-функция (Hash function) – это функция преобразующая значения ключа (например: строки, числа, файла) в целое число  Значение возвращаемое хеш-функцией называется хеш-кодом (hash code), контрольной суммой (hash sum) или хешем (hash) #define HASH_MUL 31 #define HASH_SIZE 128 // Хеш-функция для строк [KP, “Practice of Programming”] unsigned int hash(char *s) { unsigned int h = 0; char *p; for (p = s; *p != '0'; p++) h = h * HASH_MUL + (unsigned int)*p; return h % HASH_SIZE; } Thash = O(|s|)
  • 8. Хеш-функции (Hash function)  Хеш-функция (Hash function) – это функция преобразующая значения ключа (например: строки, числа, файла) в целое число  Значение возвращаемое хеш-функцией называется хеш-кодом (hash code), контрольной суммой (hash sum) или хешем (hash) #define HASH_MUL 31 #define HASH_SIZE 128 int main() { unsigned int h = hash(“ivanov”); } 8 i v a n o v 105 118 97 110 111 118
  • 9. Хеш-функции (Hash function) #define HASH_MUL 31 #define HASH_SIZE 128 unsigned int hash(char *s) { unsigned int h = 0; char *p; for (p = s; *p != '0'; p++) h = h * HASH_MUL + (unsigned int)*p; return h % HASH_SIZE; } 9 h = 0 * HASH_MUL + 105 h = 105 * HASH_MUL + 118 h = 3373 * HASH_MUL + 97 h = 104660 * HASH_MUL + 110 h = 3244570 * HASH_MUL + 111 h = 100581781 * HASH_MUL + 118 return 3118035329 % HASH_SIZE // hash(“ivanov”) = 1 i v a n o v 105 118 97 110 111 118
  • 10. Понятие коллизии (Collision) 10  Коллизия (Collision) – это совпадение значений хеш-функции для двух разных ключей Keys HashesHash function Жираф Слон Муха Цеце Волк 127 ... 05 04 03 02 01 00 Collision! hash(“Волк”) = 2 hash(“Жираф”) = 2 Существуют хеш-функции без коллизий – совершенные хеш-функции (perfect hash function)
  • 11. Разрешение коллизий (Collision resolution) 11 Метод цепочек (Chaining) – закрытая адресация Элементы с одинаковым значением хеш-функции объединяются в связный список. Указатель на список хранится в советующей ячейке хеш- таблицы.  При коллизии элемент добавляется в начало списка.  Поиск и удаление элемента требуют просмотра всего списка. Keys HashesHash function Жираф Слон Муха Цеце Волк 127 ... 05 04 03 02 01 00 Муха Цеце NULL Слон NULL Жираф Волк NULL
  • 12. Разрешение коллизий (Collision resolution) 12 Открытая адресация (Open addressing) В каждой ячейке хеш-таблицы хранится не указатель на связный список, а один элемент (ключ, значение) Если ячейка с индексом hash(key) занята, то осуществляется поиск свободной ячейки в следующих позициях таблицы Hash Элемент 0 B 1 2 3 A 4 C 5 D 6 7 Линейное хеширование (linear probing) – проверяются позиции: hash(key) + 1, hash(key) + 2, …, (hash(key) + i) mod h, … Если свободных ячеек нет, то таблица заполнена Пример:  hash(D) = 3, но ячейка с иднексом 3 занята.  Присматриваем ячейки: 4 – занята, 5 – свободна.
  • 13. Требования к хеш-функциям 13  Быстрое вычисление хэш-кода по значению ключа  Сложность вычисления хэш-кода не должна зависеть от количества n элементов в хеш-таблице  Детерминированность – для заданного значения ключа хэш-функция всегда должна возвращать одно и то же значение unsigned int hash(char *s) { unsigned int h = 0; char *p; for (p = s; *p != '0'; p++) h = h * HASH_MUL + (unsigned int)*p; return h % HASH_SIZE; }
  • 14. Требования к хеш-функциям 14  Равномерность (uniform distribution) – хеш-функция должна равномерно заполнять индексы массива возвращаемыми номерами  Желательно, чтобы все хэш-коды формировались с одинаковой равномерной распределенной вероятностью Hash Элемент 0 C, F, G 1 2 3 4 B, E 5 6 A, D, H 7 A B C D E F G H Неравномерное распределение
  • 15. Требования к хеш-функциям 15  Равномерность (uniform distribution) – хеш-функция должна равномерно заполнять индексы массива возвращаемыми номерами  Желательно, чтобы все хэш-коды формировались с одинаковой равномерной распределенной вероятностью Hash Элемент 0 C 1 A 2 D 3 H 4 B 5 G 6 E 7 F A B C D E F G H Равномерное распределение
  • 16. Эффективность хеш-таблиц 16  Хеш-таблица требует предварительной инициализации ячеек значениями NULL – трудоемкость O(h) Операция Вычислительная сложность в среднем случае Вычислительная сложность в худшем случае Add(key, value) O(1) O(1) Lookup(key) O(1 + n/h) O(n) Delete(key) O(1 + n/h) O(n) Min() O(n + h) O(n + h) Max() O(n + h) O(n + h)
  • 17. Пример хэш-функции для строк 17 unsigned int ELFHash(char *key, unsigned int mod) { unsigned int h = 0, g; while (*key) { h = (h << 4) + *key++; g = h & 0xf0000000L; if (g) h ^= g >> 24; h &= ~g; } return h % mod; }  Используются только поразрядные операции (для эффективности)
  • 18. Jenkins hash functions 18 uint32_t jenkins_hash(char *key, size_t len) { uint32_t hash, i; for (hash = i = 0; i < len; ++i) { hash += key[i]; hash += (hash << 10); hash ^= (hash >> 6); } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return hash; }
  • 19. Пример хэш-функции для чисел 19  Ключи: размер файла – число.  Значение, хранимое в словаре: название файла.  Требуется разработать хеш-функцию hash(filesize)  [0..1023] function hash(int filesize) return filesize mod 1024 end function
  • 20. Пример хэш-функции для строк 20 hash 𝑠 = 𝑖=0 𝐿−1 ℎ 𝐿−(𝑖+1) ∙ 𝑠 𝑖 = = 𝑠[0]ℎ 𝐿−1 + 𝑠[1]ℎ 𝐿−2 + ⋯ + 𝑠 𝐿 − 2 ℎ + 𝑠 𝐿 − 1 , где s – ключ (строка), L – длина строки, s[i] – код символа i
  • 21. Хеш-таблицы (Hash table) 21  Длину h хеш-таблицы выбирают как простое число  Для такой таблицы модульная хеш-функция дает равномерное распределение значений ключей hash(key) = key mod h
  • 22. Хеш-таблицы vs. Бинарное дерево поиска 22 Операция Hash table (unordered map) Binary search tree (ordered map) Add(key, value) O(m) O(nm) Lookup(key) O(m + nm) O(nm) Delete(key) O(m + nm) O(nm) Min() O(m(n + h)) O(n) Max() O(m(n + h)) O(n)  Эффективность реализации словаря хеш-таблицей (метод цепочек) и бинарным деревом поиска  Ключ – это строка из m символов  Оценка сложности для худшего случая (worst case)
  • 23. Хеш-таблицы vs. Бинарное дерево поиска 23 Операция Hash table (unordered map) Binary search tree (ordered map) Add(key, value) O(m) O(mlogn) Lookup(key) O(m + mn/h) O(mlogn) Delete(key) O(m + mn/h) O(mlogn) Min() O(m(n + h)) O(logn) Max() O(m(n + h)) O(logn)  Эффективность реализации словаря хеш-таблицей (метод цепочек) и бинарным деревом поиска  Ключ – это строка из m символов  Оценка сложности для среднего случая (average case)
  • 24. Реализация хеш-таблицы 24 #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHTAB_SIZE 71 #define HASHTAB_MUL 31 struct listnode { char *key; int value; struct listnode *next; }; struct listnode *hashtab[HASHTAB_SIZE];
  • 25. Хеш-функция 25 unsigned int hashtab_hash(char *key) { unsigned int h = 0; char *p; for (p = key; *p != '0'; p++) { h = h * HASHTAB_MUL + (unsigned int)*p; } return h % HASHTAB_SIZE; } THash = O(|key|)
  • 26. Инициализация хеш-таблицы 26 void hashtab_init(struct listnode **hashtab) { int i; for (i = 0; i < HASHTAB_SIZE; i++) { hashtab[i] = NULL; } } TInit = O(h)
  • 27. 27 Добавление элемента в хеш-таблицу void hashtab_add(struct listnode **hashtab, char *key, int value) { struct listnode *node; int index = hashtab_hash(key); // Вставка в начало списка node = malloc(sizeof(*node)); if (node != NULL) { node->key = key; node->value = value; node->next = hashtab[index]; hashtab[index] = node; } } TAdd = THash + O(1) = O(1)
  • 28. 28 Поиск элемента struct listnode *hashtab_lookup( struct listnode **hashtab, char *key) { int index; struct listnode *node; index = hashtab_hash(key); for (node = hashtab[index]; node != NULL; node = node->next) { if (strcmp(node->key, key) == 0) return node; } return NULL; } TLookup = THash + O(n) = O(n)
  • 29. Поиск элемента 29 int main() { struct listnode *node; hashtab_init(hashtab); hashtab_add(hashtab, "Tigr", 190); hashtab_add(hashtab, "Slon", 2300); hashtab_add(hashtab, "Volk", 60); node = hashtab_lookup(hashtab, "Slon"); printf("Node: %s, %dn", node->key, node->value); return 0; }
  • 30. Удаление элемента void hashtab_delete(struct listnode **hashtab, char *key) { int index; struct listnode *p, *prev = NULL; index = hashtab_hash(key); for (p = hashtab[index]; p != NULL; p = p->next) { if (strcmp(p->key, key) == 0) { if (prev == NULL hashtab[index] = p->next; else prev->next = p->next; free(p); return; } prev = p; } } 30 TDelete = THash + O(n) = O(n)
  • 31. Удаление элемента 31 int main() { struct listnode *node; /* ... */ hashtab_delete(hashtab, "Slon"); node = hashtab_lookup(hashtab, "Slon"); if (node != NULL) { printf("Node: %s, %dn", node->key, node->value); } else { printf("Key 'Slon' not foundn"); } return 0; }
  • 32. Домашнее чтение 32  Прочитать в [Sedgewick2001, С. 575] про хеш-функции для вещественных чисел  Прочитать в “Практике программирования” [KP] информацию о хеш-таблицах  Прочитать “Глава 11. Хеш-таблицы” [CLRS, С. 282]  Perfect hash function (Совершенная хеш-функция)