Открытое хеширование
Рисунок 28 показывает базовую структуру данных при открытом (внешнем) хешировании. Основная идея заключается в том, что потенциальное множество (возможно, бесконечное) разбивается на конечное число классов. Для В классов, пронумерованных от 0 до В-1, строится хеш-функция h(x) такая, что для любого элемента х исходного множества функция h(х) принимает целочисленное значение из интервала 0, ..., В-1, которое, естественно, соответствует классу, которому принадлежит элемент х. Часто «классы» называют сегментами, поэтому будем говорить, что элемент х принадлежит сегменту h(х).
Массив, называемый таблицей сегментов и проиндексированный номерами сегментов 0, 1, ..., B-1, содержит заголовки для B списков. Элемент х i-го списка — это элемент исходного множества, для которого h(x) = i.
Если сегменты примерно одинаковы по размеру, то в этом случае списки всех сегментов должны быть наиболее короткими при данном числе сегментов. Если исходное множество состоит из N элементов, тогда средняя длина списков будет N/B элементов. Если можно оценить величину N и выбрать В как можно ближе к этой величине, то в каждом списке будет один-два элемента. Тогда время выполнения операторов словарей будет малой постоянной величиной, не зависящей от N (или, что эквивалентно, от B).
Рисунок 28. Организация данных при открытом хешировании
Рассмотрим алгоритмы основных операций с хеш-таблицей, при открытом хешировании. В этих алгоритмах будем использовать структуры данных и операции с линейными однонаправленными списками, которые были описаны в п. 2.2.6.1. Поле Data в элементах списка будет здесь исполнять роль ключа, а роль указателя на список ptrHead будет играть элемент хеш-таблицы.
const
В = {подходящая константа};
type
HTableOpen = array[0..B-1] of PElement;
Кроме того, здесь используется предопределенная функция h(x), которая и является собственно реализацией хеш-функции.
procedure Clear_HTableOpen(var A: HTableOpen);
{Процедура очистки хеш-таблицы}
var
IndexSeg: integer;
begin
for IndexSeg:=0 to B-1 do
while A[IndexSeg] <> nil do
Del_LineSingleList(A[IndexSeg], A[IndexSeg]);
end;
function Find_HTableOpen(x: TypeData;
var A: HtableOpen;
var current: PElement): boolean;
{функция поиска элемента x в хеш-таблице. Принимает значение true, если найден и возвращает указатель, который устанавливается на найденный элемент, или принимает значение false и возвращает nil}
var
IndexSeg: integer; {номер сегмента}
begin
IndexSeg := h(x);
{начало списка, в котором надо искать, это A[IndexSeg]}
if Find_LineSingleList(x, A[IndexSeg], current) then
Find_HTableOpen := true
else
Find_HTableOpen := false;
end;
procedure Add_HTableOpen(x: TypeData; var A: HTableOpen);
{Процедура добавления элемента x в хеш-таблицу}
var
IndexSeg: integer; {номер сегмента}
current: PElement;
begin
if not Find_HTableOpen(x, A, current) then begin
{Если в таблице элемент уже есть, то добавлять не надо}
IndexSeg := h(x);
{Добавляем всегда в начало списка}
InsFirst_LineSingleList(x, A[IndexSeg]);
end
end;
procedure Del_HTableOpen(x: TypeData; var A: HTableOpen);
{Процедура удаления элемента x из хеш-таблицы}
var
IndexSeg: integer; {номер сегмента}
current: PElement;
begin
if Find_HTableOpen(x, A, current) then begin
{Если в таблице элемент еще есть, то удаляем}
IndexSeg := h(x);
Del_LineSingleList(A[IndexSeg], current);
end
end;
Если есть B сегментов и N элементов, хранящихся в хеш-таблице, то каждый сегмент в среднем будет иметь N/B элементов и можно ожидать, что операции добавления, поиска и удаления будут выполняться в среднем за время, пропорциональное О(1+N/B). Здесь константа 1 соответствует поиску сегмента, а N/B — поиску элемента в сегменте. Если B примерно равно N, то время выполнения операторов становится константой, независящей от N.
- Содержание
- Основные сведения
- Понятия алгоритма и структуры данных
- Анализ сложности и эффективности алгоритмов и структур данных
- Структуры данных
- Элементарные данные
- Данные числовых типов
- Данные целочисленного типа
- Данные вещественного типа
- Операции над данными числовых типов
- Данные символьного типа
- Данные логического типа
- Данные типа указатель
- Линейные структуры данных
- Множество
- Линейные списки
- Линейный однонаправленный список
- Линейный двунаправленный список
- Циклические списки
- Циклический однонаправленный список
- Циклический двунаправленный список
- Разреженные матрицы
- Матрицы с математическим описанием местоположения элементов
- Матрицы со случайным расположением элементов
- Очередь
- Нелинейные структуры данных
- Мультисписки
- Слоеные списки
- Спецификация
- Реализация
- Деревья
- Общие сведения
- Обходы деревьев
- Спецификация двоичных деревьев
- Реализация
- Основные операции
- Организация
- Представление файлов b-деревьями
- Основные операции
- Общая оценка b-деревьев
- Алгоритмы обработки данных
- Методы разработки алгоритмов
- Метод декомпозиции
- Динамическое программирование
- Поиск с возвратом
- Метод ветвей и границ
- Метод альфа-бета отсечения
- Локальные и глобальные оптимальные решения
- Алгоритмы поиска
- Поиск в линейных структурах
- Последовательный (линейный) поиск
- Бинарный поиск
- Хеширование данных
- Функция хеширования
- Открытое хеширование
- Закрытое хеширование
- Реструктуризация хеш-таблиц
- Поиск по вторичным ключам
- Инвертированные индексы
- Битовые карты
- Использование деревьев в задачах поиска
- Упорядоченные деревья поиска
- Случайные деревья поиска
- Оптимальные деревья поиска
- Сбалансированные по высоте деревья поиска
- Поиск в тексте
- Прямой поиск
- Алгоритм Кнута, Мориса и Пратта
- Алгоритм Боуера и Мура
- Алгоритмы кодирования (сжатия) данных
- Общие сведения
- Метод Хаффмана. Оптимальные префиксные коды
- Кодовые деревья
- Алгоритмы сортировки
- Основные сведения. Внутренняя и внешняя сортировка
- Алгоритмы внутренней сортировки
- Сортировка подсчетом
- Сортировка простым включением
- Сортировка методом Шелла
- Сортировка простым извлечением.
- Древесная сортировка
- Сортировка методом пузырька
- Быстрая сортировка (Хоара)
- Сортировка слиянием
- Сортировка распределением
- Сравнение алгоритмов внутренней сортировки
- Алгоритмы внешней сортировки
- Алгоритмы на графах
- Алгоритм определения циклов
- Алгоритмы обхода графа
- Поиск в глубину
- Поиск в ширину (Волновой алгоритм)
- Нахождение кратчайшего пути
- Алгоритм Дейкстры
- Алгоритм Флойда
- Переборные алгоритмы
- Нахождение минимального остовного дерева
- Алгоритм Прима
- Алгоритм Крускала
- 190000, Санкт-Петербург, ул. Б. Морская, 67