
LR2_ASD_Ikhsanovaa
.docxМинистерство науки и высшего образования Российской Федерации
Федеральное государственное бюджетное
Образовательное учреждение высшего образования
«Уфимский государственный авиационный технический университет»
Кафедра ВМК
Отсчет по лабораторной работе № 2
по дисциплине «Алгоритмы и структуры данных»
на тему: «Построение хеш-таблицы»
Выполнил:
Студент группы ПРО-232Б Э. А. Ихсанова
Проверил:
Преподаватель Г. Н. Верхотурова
Уфа – 2022
Цель работы
Целью работы является построение хеш-таблицы, содержащей заданную последовательность элементов (ключей).
Задание (Вариант 11)
Построить хеш – таблицу, содержащую последовательность из m = 52 неповторяющихся элементов размерности n = 2. Элементы генерируются с помощью датчика случайных чисел.
Хеш – функция – предпоследняя цифра квадрата ключа.
Метод разрешения конфликта – метод цепочек.
Входными данными являются:
newElement-элемент для поиска
removeElement-элемент для удаления
addElement-элемент для добавления
Changing-элемент для замены
Changed-заменяющий элемент
ht[t][15]- хеш таблица ,
где t =M/3 - размер таблицы ;
Выходные:
ht[t][15]-обновленная хеш-таблица;
Коэффициент заполнения таблицы = k/(M/3), где k – счетчик шагов ;
Среднее число шагов необходимое для заполнения таблицы b
Функция вывода хеш-таблицы(show)
void show(int t,int ht[][15])
{
for (int i = 0;i < t;i++)
{
cout << i << ") ";
for (int j = 0;j < 15;j++)
cout << ht[i][j] << " ";
cout << endl;
}
}
Диалог вызова функций:
Объявляем переменную choise, которая будет отвечать за значение выбора пользователя.
Выводим на экран 6 пункта с названиями действий
int choise;
cout << "Выберете действие\n"
<< "1.Поиск\n"<<
"2.Удаление\n"<<
"3.Добавить элемент\n"
<<"4.Заменить\n"<<
"5.Вставить рандомное число\n"<<
"6.Коэффициенты\n";
cin >> choise;
Далее объявляем инструкцию switch
switch (choise)
{
В блоке case 1 вызывается функция поиска;
Вводится newElement,
После происходит проверка на соответствие введенного числа размерам ключа (двузначное число, т. к. в условии задания n=2).
Если число не подходит по размеру, то выдать сообщение об ошибке.
Иначе, если элемент найден, то вывести сообщение о том, что он найден.
Иначе выдать сообщение о том, что не найден.
case 1:
cout << "\nВведите элемент, который хотите найти";
int newElement;
cin >> newElement;
if (newElement < 10 || newElement>99)
{
cout << "неверный размер ключа\n";
}
else
{
if (search(newElement, M, ht))
{
cout << "элемент найден " << newElement << " его индекс " << hashFunction(newElement) << "\n";
}
else
{
cout << "элемент не найден\n";
}
}
break;
Функция search(Поиска):
Объявляем переменную index для хранения хеш-индекса,
Который вычисляется по хеш-функции.
Объявляем переменную searched и присваиваем ей значение false.
Проходимся в цикле по строчкам с соответствующим индексом и проверяем его значение,
Если строчка пуста, то значение переменной searched остается неизменным.
Если же значение введенной переменной x(newElement) совпадает с существующим ключом в таблице,
то searched принимает значение true
Иначе searched остается неизменным.
bool search(int x,int M,int ht[][15])
{
int index = hashFunction(x);
bool searched=false;
for (int i = 0;i < M / 3;i++)
{
for (int j = 0;j < 15;j++)
{
if (ht[index][j] == 0)
searched = searched;
else
{
if (ht[index][j] == x)
{
searched = true;
break;
}
else
{
searched = false;
}
}
}
}
return searched;
}
case 2:
В блоке case 2 вызывается функция удаления;
Вводится removeElement,
После вызывается сама функция удаления;
cout << "Введите элемент ,который хотите удалить\n";
int removeElement;
cin >> removeElement;
remove(removeElement, M, ht);
break;
Функция remove(Удаление):
В переменную t присваиваем значение M/3, M-размер таблицы;
Объявляем переменную index для хранения хеш-индекса,
Который вычисляется по хеш-функции.
После выполняем проверку с помощью функции поиска (search) на наличие элемента в таблице,
Если такой элемент имеется, то значение ключа изменяется на -1,
И выводим новую таблицу.
Иначе выдается сообщение, что такого элемента нет и его удалить нельзя.
void remove(int x,int M,int ht[][15])
{
int t = M / 3;
int index = hashFunction(x);
if (search(x, M, ht))
{
for (int i = 0;i < M / 3;i++)
{
for (int j = 0;j < 15;j++)
{
if (ht[index][j] == x)
{
ht[index][j] = -1;
}
}
}
for (int i = 0;i < M/3;i++)
{
cout << i << ") ";
for (int j = 0;j < 15;j++)
cout << ht[i][j] << " ";
cout << endl;
}
}
else
{
cout << "Нельзя удалить элемент, т.к его нет в таблице\n";
}
}
В блоке case 3 вызывается функция добавления;
Вводится addElement,
После вызывается сама функция добавления.
И выводится новая таблица с помощью функции show.
case 3:
cout << "Введите элемент , который хотите добавить\n";
int addElement;
cin >> addElement;
add(addElement, M, ht);
show(t,ht);
break;
Функция добавления(add)
Объявляем переменную index для хранения хеш-индекса,
Который вычисляется по хеш-функции.
После выполняем проверку с помощью функции поиска(search) на наличие элемента в таблице:
Если такой элемент имеется, то выдается сообщение, что такой элемент уже есть
Иначе в цикле проходимся по строчке с соответствующим индексом и,
Если встречается 0 или -1, то в переменную flag добавляем 1,
Если флаг =1, то добавляем в пустую ячейку значение addElement.
void add(int x, int M, int ht[][15])
{
int flag = 0;
int index = hashFunction(x);
if (search(x, M, ht))
{
cout << "Такой элемент уже имеется ,его индекс "<<index<<"\n";
}
else
{
for (int i = 0;i < M / 3;i++)
{
for (int j = 0;j < 15;j++)
{
if (ht[index][j] == 0||ht[index][j]==-1)
{
flag++;
}
if (flag == 1)ht[index][j] = x;
}
}
}
}
В блоке case 4 вызывается функция добавления;
Вводятся Changed и Changing
После вызывается сама функция добавления.
case 4:
cout << "Выберете элемент ,который хотите заменить\n";
int Changed;
cin >> Changed;
cout << "Введите элемент для замены\n";
int Changing;
cin >> Changing;
swap(Changed, Changing, M, ht);
break;
Функция замены(swap)
Объявляем переменную index для хранения хеш-индекса,
Который вычисляется по хеш-функции.
После выполняем проверку с помощью функции поиска(search) на наличие первого элемента(х) в таблице:
Если он(х) имеется,
то с помощью функции удаления(remove) мы его(х) удаляем и выводим сообщение об этом
Если же второй элемент(у) не найден,
то с помощью функции добавления(add) мы его(у) добавляем
Иначе (если первый элемент(х) не найден),
То выдать сообщение, что первый элемент(х) отсутствует.
Выводим новую таблицу с помощью функции show.
void swap(int x,int y,int M,int ht[][15])
{
int index = hashFunction(x);
if (search(x, M, ht))
{
remove(x, M, ht);
cout << "Элемент " << x << " удален из " << index << endl;
if (!search(y, M, ht))
{
add(y, M, ht);
}
}
else
{
cout << "Элемент "<<x<< " отсутствует\n";
}
show(M / 3, ht);
}
В блоке case 5 вызывается функция добавления случайного элемента в таблицу;
case 5:
rnd(M, ht);
break;
Функция добавления случайного числа в таблицу(rnd):
В переменную x присваиваем случайное двузначное число.
Объявляем переменную index для хранения хеш-индекса,
Который вычисляется по хеш-функции.
Далее с помощью функции поиска проверяем наличие случайного элемента в таблице
Если он не найден, то с помощью функции добавления заносим элемент в таблицу
Выводим сообщение о том, что случайный элемент был добавлен в таблицу
Выводим новую таблицу на экран с помощью функции(show).
void rnd(int M,int ht[][15])
{
int x = rand() % 90 + 10;
int index = hashFunction(x);
if (!search(x, M, ht))
{
add(x, M, ht);
}
cout << "Добавлено новое число: " << x <<" Его индекс "<< index<<"\n";
show(M / 3, ht);
}
В блоке case 6 выводим коэффициент заполнения таблицы и среднее число шагов необходимых для ее заполнения.
case 6:
a(t, ht, M);
cout << "\n";
cout << b(t, ht, M);
break;
В блоке case 7 в переменную exit, отвечающую за выход из цикла while(true), в котором выполняется инструкция switch, заносим значение true. Тем самым провоцируем выход из цикла.
case 7:
exit = true;
break;
В блоке default при неверном введенном значении choise выдаем сообщение об ошибке.
default:
cout << "Ошибка\n";
break;
}
Результаты работы функций
Функция поиска
2)Функция удаления
3)Функция добавления
4)Функция замены
Функция добавляющую случайное значение в таблицу
Примеры работы программы
1.Элемент в таблице не найден
2.Попытка удаления не существующего элемента
3.Попытка добавления уже имеющегося элемента в таблицу
4.Попытка замены не существующего элемента
Ключи:
1) 35 14) 10 27) 88 40) 83
2) 45 15) 65 28) 86 41) 78
3) 90 16) 30 29) 50 42) 93
4) 28 17) 67 30) 41 43) 79
5) 27 18) 61 31) 77 44) 59
6) 87 19) 36 32) 96 45) 55
7) 80 20) 68 33) 47 46) 33
8) 24 21) 22 34) 40 47) 64
9) 54 22) 52 35) 44 48) 43
10) 98 23) 70 36) 49 49) 75
11) 18 24) 74 37) 42 50) 17
12) 92 25) 51 38) 34 51) 66
13) 53 26) 13 39) 48 52) 82
Хеш-таблица:
0) 90 80 98 53 10 30 52 70 51 50 47 40 49 48 0
1) 54 96 0 0 0 0 0 0 0 0 0 0 0 0 0
2) 35 45 27 18 65 61 68 77 55 75 82 0 0 0 0
3) 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4) 88 93 79 43 0 0 0 0 0 0 0 0 0 0 0
5) 34 66 0 0 0 0 0 0 0 0 0 0 0 0 0
6) 87 92 13 42 0 0 0 0 0 0 0 0 0 0 0
7) 24 74 0 0 0 0 0 0 0 0 0 0 0 0 0
8) 28 67 22 41 83 78 59 33 17 0 0 0 0 0 0
9) 36 86 64 0 0 0 0 0 0 0 0 0 0 0 0
10) -
11) -
12) -
13) -
14) -
15) -
16) -
Коэффициент заполнения таблицы :
0.529412
Среднее число шагов, необходимых для размещения элементов в таблицу: 4.84615
Формула расчета требуемых параметров хеш-таблицы
коэффициент заполнения таблицы равен отношению занятых ячеек к размеру
хеш-таблицы.
среднее число шагов, необходимых для размещения элементов в таблицу равно отношению суммы всех шагов для размещения каждого элемента к количеству всех элементов