Сиакод 1
.docxФГБОУ ВО
Уфимский Государственный Авиационный Технический Университет
Кафедра ВМиК
Отчет по лабораторной работе №1
«Построение хэш-таблицы»
по дисциплине
«Структуры и алгоритмы компьютерной обработки данных»
Выполнил:
студент группы МО-217
Шакиров Айдар Рушанович
Проверил:
Канд. техн. наук, доцент
Верхотурова Галина Николаевна
Уфа 2019
Цель работы
Построить хэш-таблицу, содержащую последовательность из m = 56 элементов размерности n = 5. Элементы генерируются с помощью датчика случайных чисел.
Хэш-функция - f(k) =(k / 19) mod t.
Метод разрешения коллизий - квадратичные пробы.
Ход выполнения работы:
Создается структура хэш-таблицы.
const int N = 56; //кол-во элементов
struct MyHashTable
{
public int[] table; //сама таблица
public bool[] busy; //таблица занятости ячеек
public int SizeTable { get { return table.Length; } }
public MyHashTable(int sizeTable) //конструктор
{
table = new int[sizeTable];
busy = new bool[sizeTable];
}
}
Для хранения данных используются два массива, в table хранятся сами ключи, а в busy хранятся флаги занятости соответствующих элементов в table.
Генерируем ключи в виде пятизначных чисел с помощью генератора псевдослучайных чисел в массив array. Затем их выводим на экран.
//создается массив элементов размерности N = 56
var array = new int[N];
var rnd = new Random();
//генерируются ключи зазмерности m = 5
Console.WriteLine("Сгенерированные ключи:");
for (int i = 0; i < array.Length; i++)
{
array[i] = rnd.Next(10000, 100000);
Console.Write($"[{i+1}] = { array[i]}\t");
if(((i+1) % 4 == 0) && (i!=0))
Console.WriteLine();
}
Вычисляем размер хэш-таблицы (в 1.5 раза больше элементов, которые собираемся хранить) и создаем ее.
int sizeTable = (int)Math.Round(N * 1.5);
var hashTable = new MyHashTable(sizeTable);
var kolvoProb = 0;
Для хранения суммарного количества создаем переменную kolvoProb.
Заполняем хэш-таблицу сгенерированными ключами.
for (int i = 0; i < array.Length; i++)
{
var index = Hash(array[i], hashTable.SizeTable); //Использование хэш-функции
var index0 = index; //Начальный индекс
for (int j = 1; ; j++) //кол-во проб
{
//если ячейка таблицы свободна, то вносим значение элемента
if (!hashTable.busy[index])
{
hashTable.table[index] = array[i];
hashTable.busy[index] = true;
kolvoProb++;
Console.WriteLine($"В таблицу вносится [{i+1}]={array[i]} по индексу {index}");
break;
}
//если занята, то используем метод разрешения коллизий
//index0 хранит значение первой пробы
else
{
Console.WriteLine($"Индекс {index} занят. Будет доп. попытка №{j+1}");
index = (index0 + (j*j)) % sizeTable;
kolvoProb++;
}
}
}
...
static int Hash(int key, int sizeTable) //хэш-функция
{
return (key / 19) % sizeTable;
}
В цикле перебираем все элементы массива ключей. Каждый ключ хэшируется, на выходе получается индекс. Вносим в хэш-таблицу ключ по полученному индексу. Если ячейка занята, то проводим разрешение коллизий методом квадратичных проб index = (index0 + (j*j)) % sizeTable, где j – номер попытки, а index0 - индекс, полученный при первоначальном хэшировании ключа.
Выводим получившуюся хэш-таблицу на экран. Вычисляем и выводим коэффициент заполнения таблицы и среднее число проб.
Console.WriteLine("\n\nХэш-таблица:");
for (int i = 0; i < hashTable.SizeTable; i++)
{
Console.Write($"[{i}] = {hashTable.table[i]} \t");
if (((i + 1) % 4 == 0) && (i != 0))
Console.WriteLine();
}
Console.WriteLine("Коэффициент заполнения таблицы = {0:0.000}", (double)N / sizeTable);
Console.WriteLine("Среднее число проб = {0:0.000}", (double)kolvoProb / N);
Console.WriteLine("Готово");
Заключение:
В ходе лабораторной работы была изучена и построена хэш-таблица, использующая метод разрешения коллизий – квадратичные пробы.