Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика и ВТ Брукшир.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
5.07 Mб
Скачать

8.4 Хэширование

Хотя индексирование обеспечивает относительно быстрый доступ к записям в структуре хранения данных, оно достигает этого за счет поддержки индекса. Хэширование (hashing) — это способ, обеспечивающий похожий доступ без излишней нагрузки. Этот способ позволяет находить запись при помощи ключевого значения, но вместо поиска ключа в индексе хэширование определяет положение записи исходя из значения ключа. Процесс можно описать так: пространство хранилища данных разделено на несколько секций, называемых сегментами (bucket). Записи распределены по блокам согласно алгоритму (называемому хэш-функцией), который преобразует ключевые значения в номера сегментов. Каждая запись хранится в сегменте, идентифицируемом при помощи этого процесса. Таким образом, чтобы найти элемент в структуре хранилища, нужно применить хэш-функцию к идентификационному ключу этого элемента и определить соответствующий сегмент; затем считать содержимое сегмента и найти в нем нужную запись. Результат применения хэширования к структуре хранения на запоминающем устройстве называется хэш-файлом (hash file). Результат применения хэш-функции к структуре хранения в оперативной памяти обычно называется хэш-таблицей (hash table).

8.4.1Хэш-система

Применим концепцию хэширования к классическому файлу сотрудников. Сначала на запоминающем устройстве выделим несколько свободных областей, которые будут играть роль сегментов. Выбор их количества и размера мы обсудим позже. Сейчас же предположим, что мы создали 40 сегментов, к которым будем обращаться как к сегменту № 0, сегменту № 1 и так далее до сегмента № 39.

Предположим, что в качестве ключа для идентификации записи сотрудника будет использоваться его идентификационный номер. Наша следующая задача — разработать хэш-функцию для преобразования этих ключей в номера сегментов. Хотя идентификаторы могут иметь форму 25X3Z или J2X35, то есть не являться числовыми значениями, они хранятся в виде комбинаций битов, и мы можем интерпретировать эти комбинации как номера. Воспользовавшись числовой интерпретацией, разделим каждый ключ на количество сегментов и запишем остаток, который в нашем случае будет целым числом от 0 до 39. Таким образом, мы можем использовать остаток от деления для идентификации одного из наших 40 сегментов (рис. 8.10).

Искусство хэширования

Многое уже было написано о хэшировании. Цель всех исследований — найти эффективный алгоритм хэширования, равномерно распределяющий записи по сегментам. Один из способов, называемый методом середины квадрата (midsquare method), заключается в умножении ключевого значения на само себя и выборе средних цифр из результата. Эти цифры и являются номером сегмента. Другой метод называется методом выбора (extraction method), при этом выбираются цифры, находящиеся на определенных позициях в ключе, и номер сегмента создается путем перестановки этих цифр каким-либо предопределенным методом. Сегодня достаточно популярны различные вариации процесса деления, который мы обсуждали в этом разделе. Главная задача при этом — избежать ключей, подчиненных какой-либо системе, так как система среди ключей приводит к тому, что сегменты также выбираются согласно системе. По этой причине для функции хэширования лучше использовать последние несколько цифр в телефонных номерах, так как цифры в начале номера обычно представляют географическую область, населенный пункт и т. д. Аналогично, не рекомендуется использование имен в качестве ключей, так как в зависимости от региона определенные имена встречаются чаще (сравните, например, Смит, Иван, Мухаммед и Дешпанде).

Используя эти вычисления как хэш-функцию, мы перейдем к созданию файла. Будем брать записи по одной, применять к их ключу нашу хэш-функцию деления на 40, получать номера сегмента и затем передавать записи в соответствующие сегменты (рис. 8.11). Позже, если нам потребуется считать определенную запись, мы применим хэш-функцию к ее ключу, найдем соответствующий сегмент и произведем поиск этой записи в сегменте.