Метод функции середины квадрата




Следующей хеш-функцией является функция середины квадрата. Значение ключа преобразуется в число, это число затем возводится в квадрат, из него выбираются несколько средних цифр и интерпретируются как адрес записи.

Метод свертки

Еще одной хеш-функцией можно назвать функцию свертки. Цифровое представление ключа разбивается на части, каждая из которых имеет длину, равную длине требуемого адреса. Над частями производятся определенные арифметические или поразрядные логические операции, результат которых интерпретируется как адрес. Например, для сравнительно небольших таблиц с ключами – символьными строками неплохие результаты дает функция хеширования, в которой адрес записи получается в результате сложения кодов символов, составляющих строку-ключ.

В качестве хеш-функции также применяют функцию преобразования системы счисления. Ключ, записанный как число в некоторой системе счисления P, интерпретируется как число в системе счисления Q>P. Обычно выбирают Q=P+1. Это число переводится из системы Q обратно в систему P, приводится к размеру пространства записей и интерпретируется как адрес.

Открытое хеширование

Основная идея базовой структуры при открытом (внешнем) хешировании заключается в том, что потенциальное множество (возможно, бесконечное) разбивается на конечное число классов. Для В классов, пронумерованных от 0 до В-1, строится хеш-функция h(x) такая, что для любого элемента х исходного множества функция h(x) принимает целочисленное значение из интервала 0,1,...,В-1, соответствующее классу, которому принадлежит элемент х. Часто классы называют сегментами, поэтому будем говорить, что элемент х принадлежит сегменту h(x). Массив, называемый таблицей сегментов и проиндексированный номерами сегментов 0,1,...,В-1, содержит заголовки для B списков. Элемент х, относящийся к i -му списку – это элемент исходного множества, для которого h(x)=i.

Если сегменты примерно одинаковы по размеру, то в этом случае списки всех сегментов должны быть наиболее короткими при данном числе сегментов. Если исходное множество состоит из N элементов, тогда средняя длина списков будет N/B элементов. Если можно оценить величину N и выбрать В как можно ближе к этой величине, то в каждом списке будет один или два элемента. Тогда время выполнения операторов словарей будет малой постоянной величиной, не зависящей от N.

Закрытое хеширование

При закрытом (внутреннем) хешировании в хеш-таблице хранятся непосредственно сами элементы, а не заголовки списков элементов. Поэтому в каждой записи (сегменте) может храниться только один элемент. При закрытом хешировании применяется методика повторного хеширования. Если осуществляется попытка поместить элемент х в сегмент с номером h(х), который уже занят другим элементом (коллизия), то в соответствии с методикой повторного хеширования выбирается последовательность других номеров сегментов h1(х),h2(х),..., куда можно поместить элемент х. Каждое из этих местоположений последовательно проверяется, пока не будет найдено свободное. Если свободных сегментов нет, то, следовательно, таблица заполнена, и элемент х добавить нельзя.

При поиске элемента х необходимо просмотреть все местоположения h(x), h1(х), h2(х),..., пока не будет найден х или пока не встретится пустой сегмент. Чтобы объяснить, почему можно остановить поиск при достижении пустого сегмента, предположим, что в хеш-таблице не допускается удаление элементов. Пусть h3(х) – первый пустой сегмент. В такой ситуации невозможно нахождение элемента х в сегментах h4(х),h5(х) и далее, так как при вставке элемент х вставляется в первый пустой сегмент, следовательно, он находится где-то до сегмента h3(х). Но если в хеш-таблице допускается удаление элементов, то при достижении пустого сегмента, не найдя элемента х, нельзя быть уверенным в том, что его вообще нет в таблице, так как сегмент может стать пустым уже после вставки элемента х. Поэтому, чтобы увеличить эффективность данной реализации, необходимо в сегмент, который освободился после операции удаления элемента, поместить специальную константу, которую назовем, например,DEL. В качестве альтернативы специальной константе можно использовать дополнительное поле таблицы, которое показывает состояние элемента. Важно различать константы DEL и NULL – последняя находится в сегментах, которые никогда не содержали элементов. При таком подходе выполнение поиска элемента не требует просмотра всей хеш-таблицы. Кроме того, при вставке элементов сегменты, помеченные константой DEL, можно трактовать как свободные, таким образом, пространство, освобожденное после удаления элементов, можно рано или поздно использовать повторно. Но если невозможно непосредственно сразу после удаления элементов пометить освободившиеся сегменты, то следует предпочесть закрытому хешированию схему открытого хеширования.

Существует несколько методов повторного хеширования, то есть определения местоположений h(x),h1(х),h2(х),...:

· линейное опробование;

· квадратичное опробование;

· двойное хеширование.

Линейное опробование сводится к последовательному перебору сегментов таблицы с некоторым фиксированным шагом:

адрес=h(x)+ci,

где i – номер попытки разрешить коллизию;

c – константа, определяющая шаг перебора.

При шаге, равном единице, происходит последовательный перебор всех сегментов после текущего. Квадратичное опробованиеотличается от линейного тем, что шаг перебора сегментов нелинейно зависит от номера попытки найти свободный сегмент:

адрес=h(x)+ci+di2,

где i – номер попытки разрешить коллизию,

c и d – константы.

Благодаря нелинейности такой адресации уменьшается число проб при большом числе ключей-синонимов. Однако даже относительно небольшое число проб может быстро привести к выходу за адресное пространство небольшой таблицы вследствие квадратичной зависимости адреса от номера попытки.

Еще одна разновидность метода открытой адресации, которая называется двойным хешированием, основана на нелинейной адресации, достигаемой за счет суммирования значений основной и дополнительной хеш-функций:

адрес=h(x)+ih2(x).

Очевидно, что по мере заполнения хеш-таблицы будут происходить коллизии, и в результате их разрешения очередной адрес может выйти за пределы адресного пространства таблицы. Чтобы это явление происходило реже, можно пойти на увеличение длины таблицы по сравнению с диапазоном адресов, выдаваемым хеш-функцией. С одной стороны, это приведет к сокращению числаколлизий и ускорению работы с хеш-таблицей, а с другой – к нерациональному расходованию памяти. Даже при увеличении длины таблицы в два раза по сравнению с областью значений хеш-функции нет гарантии того, что в результате коллизий адрес не превысит длину таблицы. При этом в начальной части таблицы может оставаться достаточно свободных сегментов. Поэтому на практике используют циклический переход к началу таблицы.

Однако в случае многократного превышения адресного пространства и, соответственно, многократного циклического перехода к началу будет происходить просмотр одних и тех же ранее занятых сегментов, тогда как между ними могут быть еще свободныесегменты. Более корректным будет использование сдвига адреса на 1 в случае каждого циклического перехода к началу таблицы. Это повышает вероятность нахождения свободных сегментов.

В случае применения схемы закрытого хеширования скорость выполнения вставки и других операций зависит не только от равномерности распределения элементов по сегментам хеш-функцией, но и от выбранной методики повторного хеширования(опробования) для разрешения коллизий, связанных с попытками вставки элементов в уже заполненные сегменты. Например, методика линейного опробования для разрешения коллизий – не самый лучший выбор.

Как только несколько последовательных сегментов будут заполнены, образуя группу, любой новый элемент при попытке вставки в эти сегменты будет вставлен в конец этой группы, увеличивая тем самым длину группы последовательно заполненных сегментов. Другими словами, для поиска пустого сегмента в случае непрерывного расположения заполненных сегментов необходимо просмотреть больше сегментов, чем при случайном распределении заполненных сегментов. Отсюда также следует очевидныйвывод, что при непрерывном расположении заполненных сегментов увеличивается время выполнения вставки нового элемента и других операций.

 

Задание

1. Создать динамический массив из записей (в соответствии с вариантом), содержащий не менее 100 элементов. Для заполнения элементов массива использовать ДСЧ.

2. Предусмотреть сохранение массива в файл и загрузку массива из файла.

3. Предусмотреть возможность добавления и удаления элементов из массива (файла).

4. Выполнить поиск элемента в массиве по ключу в соответствии с вариантом. Для поиска использовать хэш-таблицу.

5. Подсчитать количество коллизий при размере хэш-таблицы 40, 75 и 90 элементов.

Вариант Данные Ключ (string) Хэш-функция Метод рехеширования
  ФИО, группа, рейтинг ФИО H(k)=k mod M Метод цепочек
  ФИО, №счета, сумма №счета H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод открытой адресации
  ФИО, №счета, сумма ФИО H(k)=k mod M Метод открытой адресации
  ФИО, №паспорта, адрес №паспорта H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод цепочек
  ФИО, №паспорта, адрес ФИО H(k)=k mod M Метод цепочек
  ФИО, №паспорта, адрес Адрес H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод открытой адресации
  ФИО, №телефона, адрес №телефона H(k)=k mod M Метод открытой адресации
  ФИО, №телефона, адрес ФИО H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод цепочек
  ФИО, №телефона, адрес Адрес H(k)=k mod M Метод цепочек
  ФИО, №паспорта, №телефона №телефона H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод открытой адресации
  ФИО, №паспорта, №телефона №паспорта H(k)=k mod M Метод открытой адресации
  ФИО, №паспорта, №телефона ФИО H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод цепочек
  ФИО, дата_рождения, адрес дата_рождения H(k)=k mod M Метод цепочек
  ФИО, дата_рождения, адрес адрес H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод открытой адресации
  ФИО, дата_рождения, адрес ФИО H(k)=k mod M Метод открытой адресации
  ФИО, дата_рождения, №телефона дата_рождения H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод цепочек
  ФИО, дата_рождения, №телефона ФИО H(k)=k mod M Метод цепочек
  ФИО, дата_рождения, №телефона №телефона H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод открытой адресации
  ФИО, дата_рождения, №паспорта, №паспорта, H(k)=k mod M Метод открытой адресации
  ФИО, дата_рождения, №паспорта, дата_рождения, H(k)= [M (kAmod1)], 0<A<1, mod1 – получение дробной части, [] – получение целой части Метод цепочек

 

Методические указания

1. Для выбора действий использовать меню.

2. Для добавления элементов в файл использовать вспомогательную структуру для хранения элементов в оперативной памяти (список). Добавление должно осуществляться в начало, в конец файла и на позицию с заданным номером.

3. Удаление должно осуществляться по ключевому полю и по номеру. Удаляемые из файла записи помечаются как удаленные, когда их количество превысит половину файла, их можно удалять. При удалении использовать вспомогательную структуру для хранения элементов в оперативной памяти (список).

4. Предусмотреть возможность отмены последней операции удаления.

5. Корректировка выполняется по ключу и по номеру.

6. Предусмотреть команду «Сохранить изменения», по которой измененные данные из списка переписываются в файл.

Содержание отчета

1. Постановка задачи (общая и для конкретного варианта).

2. Анализ задачи.

3. Проектирование функций для реализации поставленных задач (название функции, назначение, входные параметры, результат).

4. Тесты для каждой функции.

5. Тест для комплексной задачи (интеграция).

6. Листинг программы.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-06-11 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: