Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Лабораторная работа № 15. Хэш-таблицы c открытой адресацией



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

Существуют два основных варианта хеш-таблиц: с цепочками и открытой адресацией. Хеш-таблица содержит некоторый массив, элементы которого есть пары (хеш-таблица с открытой адресацией) или списки пар (хеш-таблица с цепочками).

Задание Краткие теоретические сведения  
1. Пункты 1, 2, 3 содержат программный код проекта, в котором реализована хэш-таблица с открытой адресацией. В правой части данного пункта записан заголовочный файл Hash.h. Написать комментарии к программному коду.  
  #pragma once #define HASHDEL (void*)-1 struct Object { void** Data; Object(int, int (*)(void*)); int Size; int N; int (*GetKey)(void*); bool Insert(void*); int SearchInd(int key); void* Search(int key); void* Delete(int key); bool Delete(void*); void Scan(void(*f)(void*)); }; static void* DEL=(void*)HASHDEL; Object Create(int size, int (*getkey)(void*)); #undef HASHDEL
2. В правой части данного пункта представлена структура, главная функция проекта и две вспомогательных функции. Написать комментарии к программе.    
#include "stdafx.h" #include "Hash.h" #include <iostream> using namespace std; struct AAA { int key; char *mas; AAA(int k,char*z) { key=k; mas=z; } AAA() {} }; int key(void* d) { AAA* f = (AAA*)d; return f->key; } void AAA_print(void* d) { cout<<" ключ "<<((AAA*)d)->key<<" - " <<((AAA*)d)->mas<<endl; } int _tmain(int argc, _TCHAR* argv[]) {setlocale(LC_ALL, "rus"); AAA a1(1,"one"), a2(2,"two"), a3(4,"three"), a4 (2,"fo"); int siz=10; cout<<"Введите размер хэш-таблицы" <<endl; cin>>siz; Object H=Create(siz,key);//создать int choise; int k; for(;;) {cout<<"Меню:"<<endl; cout<<"1 - вывод хэш-таблицы"<<endl; cout<<"2 - добавление элемента"<<endl; cout<<"3 - удаление элемента"<<endl; cout<<"4 - поиск элемента"<<endl; cout<<"0 - выход"<<endl; cout<<"сделайте выбор"<<endl; cin>>choise; switch(choise){ case 0: exit(0); case 1: H.Scan(AAA_print); break; case 2: {AAA *a = new AAA; char *str = new char [20]; cout<<"введите ключ"<<endl; cin>>k; a->key=k; cout<<"введите строку"<<endl; cin>>str; a->mas=str; if(H.N == H.Size) cout<<"Таблица заполнена"<<endl; else H.Insert(a); } break; case 3: { cout<<"введите ключ для удаления"<<endl; cin>>k; H.Delete(k); } break; case 4: {cout<<"введите ключ для поиска"<<endl; cin>>k; if (H.Search(k)==NULL) cout<<"Элемент не найден"<<endl; else AAA_print(H.Search(k)); } break; } } return 0; }
3. В правой части записан программный модуль Hash.cpp. Написать комментарии к программному коду. Сформировать программный код в один проект и выполнить его.
#include "stdafx.h" #include "Hash.h" #include <iostream> int HashFunction(int key, int size, int p)//хэш-функция { double key2=5*((0.6180339887499*key)-int((0.6180339887499*key))); return (p+key)%size; //return ((int)(p+fmod(((key*(sqrt(5.0)-1))/2), 1)))%size; } int Next_hash(int hash, int size, int p) { return (hash+5*p+3*p*p)%size; } Object Create(int size, int(*getkey)(void*)) { return *(new Object(size,getkey)); } Object::Object(int size,int(*getkey)(void*)) { N=0; this->Size = size; this->GetKey=getkey; this->Data=new void*[size]; for(int i=0; i<size; ++i) Data[i]=NULL; } bool Object::Insert(void* d) { bool b=false; if(N!=Size) for(int i=0, t=GetKey(d), j=HashFunction(t, Size, 0); i!=Size&&!b; //j=HashFunction(t,Size,++i)) j= Next_hash(j, Size, ++i)) if(Data[j]==NULL||Data[j]==DEL) { Data[j]=d; N++; b=true; } return b; } int Object::SearchInd(int key) {int t=-1; bool b=false; if(N!=0) for(int i=0,j=HashFunction(key,Size,0); Data[j]!=NULL&&i!=Size&&!b; j=HashFunction(key, Size, ++i)) if(Data[j]!= DEL) if(GetKey(Data[j])==key) { t=j; b=true; } return t; } void* Object::Search(int key) { int t=SearchInd(key); return(t>=0)?(Data[t]):(NULL); } void* Object::Delete(int key) { int i=SearchInd(key); void* t=Data[i]; if(t!=NULL) {Data[i]=DEL; N--;} return t; } bool Object::Delete(void* d) { return(Delete(GetKey(d))!=NULL); } void Object::Scan(void(*f)(void*)) {for(int i = 0; i < this->Size; i++) {std::cout<<" Элемент"<<i; if ((this->Data)[i]==NULL) std::cout<<" пусто"<<std::endl; else if ((this->Data)[i]==DEL) std::cout<<" удален"<<std::endl; else f((this->Data)[i]); } }
 

4. Добавить в проект функцию расчета коэффициента заполнения хэш-таблицы (альфа = n/m – число хранимых элементов /размер массива хэш).

Использовать функции при моделировании. Провести исследование построения хэш-таблиц разного размера (например, 16, 32 или 32, 64, 128) с коллизиями. Исследовать время поиска в построенных в соответствии со своим вариантом хэш-таблицах.

№ варианта Условие задачи
Варианты с 1по8 Изменить функцию вычисления хэш для решения коллизии на квадратичную функцию, которая строится на основе формулы: h(key, i) = (h'(key) + с1*i+ c2*i2) mod hashTableSize.
Вариантыс 9по16 Изменить функцию вычисления хэш на мультипликативную функцию, которая строится на основе формулы: H(key) = [hashTableSize(key*A mod 1)], где key*A mod 1 – дробная часть key*A, A = (sqrt(5) - 1) / 2 = 0,6180339887499

В начало практикума






Дата публикования: 2015-02-18; Прочитано: 817 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2025 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (1.139 с)...