Professional Documents
Culture Documents
АСД МВтЗ (у) -2021
АСД МВтЗ (у) -2021
“ЗАТВЕРДЖУЮ”
Декан ТЕФ
_________ Є. М. Письменний
(підпис) (ініціали, прізвище)
“____”___________ 20__ р.
_________ ______________
(підпис) (ініціали, прізвище)
“____”___________ 20__ р.
Київ – 2021
Методичні вказівки та завдання до лабораторних занять кредитного модуля
«Алгоритми та структури даних» для бакалаврів напрямку підготовки «Автоматизація
та комп'ютерно-інтегровані технології» // Укладач Грудзинський Ю.Є. – Київ: НТУУ "КПІ
ім. І. Сікорського". – 2021 р. – 55 с.
Відповідальний
редактор ______________________________
2
ЗМІСТ
ВИМОГИ ДО ВИКОНАННЯ, ОФОРМЛЕННЯ І ЗДАЧІ ЛАБОРАТОРНИХ
РОБІТ ............................................................................................................................ 5
Оформлення.............................................................................................................. 5
Нарахування балів ................................................................................................... 6
Самостійне виконання завдань ............................................................................... 6
Допуск до лабораторної роботи ............................................................................. 6
Захист завдань .......................................................................................................... 6
Угоди про стиль кодування .................................................................................... 6
Додаткові вимоги до написання програм .............................................................. 6
Рекомендації по створенню власних проектів в середовищі Visual Studio ....... 7
ЛАБОРАТОРНА РОБОТА №1. АЛГОРИТМИ СОРТУВАННЯ ......................... 9
1.1. Алгоритми порядку складності O(N2) ......................................................... 9
1.2. Алгоритми порядку складності O(N*log(N)) ............................................ 10
1.3. Алгоритми порядку складності O(N)......................................................... 13
1.4. Опис роботи ................................................................................................. 15
1.5. Вимоги до виконання роботи ..................................................................... 15
1.6. Зміст звіту по лабораторній роботі ............................................................ 15
1.7. Варіанти завдань .......................................................................................... 16
1.8. Контрольні питання ..................................................................................... 17
ЛАБОРАТОРНА РОБОТА №2. ЛІНІЙНІ АБСТРАКТНІ СТРУКТУРИ ДАНИХ
(АТД) 18
2.1. Алгоритми роботи з АТД............................................................................ 18
2.1.1. Робота з двонапрямленим списком ........................................................ 18
2.1.2. Робота з циклічним (кільцевим) списком .............................................. 19
2.2. Опис виконання роботи .............................................................................. 20
2.3. Вимоги до виконання роботи ..................................................................... 21
2.4. Зміст звіту по лабораторній роботі ............................................................ 21
2.5. Варіанти завдань .......................................................................................... 21
2.6. Контрольні питання ..................................................................................... 22
ЛАБОРАТОРНА РОБОТА №3. БІНАРНІ ДЕРЕВА ............................................ 23
3.1. Представлення бінарного дерева в пам'яті комп'ютера ........................... 23
3.2. Траверс (обхід) бінарних дерев .................................................................. 23
3.2.1. Обхід в прямому порядку ........................................................................ 24
3.2.2. Симетричний обхід .................................................................................. 25
3.2.3. Обхід у зворотному порядку ................................................................... 26
3.2.4. Обхід в ширину......................................................................................... 27
3.3. Створення дерева ......................................................................................... 29
3.4. Пошук вершини у бінарному дереві .......................................................... 30
3.5. Включення нового елемента у бінарне дерево ......................................... 31
3.6. Видалення вершини з бінарного дерева пошуку ..................................... 33
3.6.1. Випадок 1: видалення вершини, яка не має нащадків. ......................... 33
3.6.2. Випадок 2: видалення вершини з одним нащадком. ............................ 33
3
3.6.3. Випадок 3: видалення вершини з двома нащадками. ........................... 34
3.7. Видалення бінарного дерева....................................................................... 37
3.8. Опис виконання роботи .............................................................................. 37
3.9. Вимоги до виконання роботи ..................................................................... 38
3.10. Зміст звіту по лабораторній роботі ......................................................... 38
3.11. Варіанти завдань ....................................................................................... 38
3.12. Контрольні питання.................................................................................. 38
ЛАБОРАТОРНА РОБОТА №4. АЛГОРИТМИ І ПРИНЦИПИ ХЕШУВАННЯ.
РОЗВ'ЯЗАННЯ КОЛІЗІЙ 40
4.1. Загальні поняття і визначення .................................................................... 40
4.2. Приклад організації хеш-таблиці ............................................................... 40
4.3. Функції хешування ...................................................................................... 41
4.3.1. Отримання залишку ................................................................................. 41
4.3.2. Мультиплікативний метод....................................................................... 42
4.3.3. Метод середини квадрата ........................................................................ 42
4.3.4. Перетворення символьних ключів.......................................................... 42
4.4. Колізії і їх розв'язання ................................................................................. 42
4.5. Основні операції з хеш-таблицею .............................................................. 43
4.6. Опис виконання роботи .............................................................................. 43
4.7. Вимоги до виконання роботи ..................................................................... 44
4.8. Зміст звіту по лабораторній роботі ............................................................ 44
4.9. Варіанти завдань .......................................................................................... 44
4.10. Контрольні питання.................................................................................. 46
РЕКОМЕНДОВАНА ЛІТЕРАТУРА ........................................................................ 47
Базова ...................................................................................................................... 47
Допоміжна .............................................................................................................. 47
Додаткова література, видана на українській мові ............................................ 48
ДОДАТОК 1. ВИМОГИ ДО ОФОРМЛЕННЯ КОДУ ПРОГРАМ НА МОВІ СІ 49
Угоди по ідентифікаторам .................................................................................... 49
Підбір ідентифікаторів .................................................................................... 49
Написання ідентифікаторів............................................................................. 49
Угоди по самодокументованих програмах ......................................................... 50
Коментарі........................................................................................................... 50
Специфікація функцій........................................................................................ 51
Специфікація програмного файлу або модуля ................................................ 52
Угоди по читабельності програм ......................................................................... 52
"Драбинка" .......................................................................................................... 52
Довжина рядків програмного тексту ............................................................. 54
Інші рекомендації ............................................................................................... 54
4
ВИМОГИ ДО ВИКОНАННЯ, ОФОРМЛЕННЯ І ЗДАЧІ ЛАБОРАТОРНИХ
РОБІТ
Оформлення
5
Нарахування балів
Завдання кожної лабораторної роботи оцінюється в задану кількість балів залежно
від складності завдань. Бали, фактично отримані студентом за виконання роботи,
залежать від ступеня відповідності виконаної програми вимогам завдання, оформлення
та власних знань студента.
Доречне прислів’я: «що посієш, те й пожнеш».
Для кожної лабораторної роботи встановлені терміни її виконання. В залежності від
фактичних термінів здачі роботи від балів, набраних студентом, віднімається штраф,
встановлений викладачем.
Доречне прислів’я: «куй залізо, поки гаряче».
Самостійне виконання завдань
Робота повинна бути виконана студентом самостійно. Випадки виявлення плагіату
будуть каратися виставленням балів з негативним коефіцієнтом.
Доречне прислів’я: «на чужому горбі в рай не потрапиш».
Допуск до лабораторної роботи
Перед тим, як приступити до виконання відповідної лабораторної роботи згідно
свого варіанту кожний студент бригади повинен відповісти на контрольні питання
викладача. Тільки після цього бригада студентів буде допущена до виконання роботи.
Студент(и) бригади, недопущені до виконання лабораторної роботи, відмічаються у
журналі групи як відсутні.
Перед виконанням лабораторної роботи у кожного студента бригади повинен бути:
- протокол лабораторної роботи, написаний власноруч (без висновків та
результатів роботи);
- в протоколі повинна бути присутня схема алгоритму, виконана згідно діючого
стандарту;
- в протоколі повинен бути присутнім текст програм на відповідних мовах,
згідно завдання;
- в протоколі повинен бути присутнім розділ "Очікувані результати роботи".
Захист завдань
Для контролю засвоєння студентом навчальних матеріалів та контролю
самостійності виконання лабораторної роботи, робота, що здається повинна бути
захищена викладачу. Нерозуміння студентом принципів роботи алгоритму або
програми своєї роботи може бути розцінено, як спроба здачі чужої роботи (див.
попередній розділ).
Угоди про стиль кодування
При написанні програмного коду слід дотримуватися певних правил оформлення,
про які докладно написано в Додатку 1. Невідповідність програми даним вимогам може
з'явитися причиною зниження балів за роботу.
Додаткові вимоги до написання програм
При виконанні кожної лабораторної роботи студент повинен передбачати у своєму
програмному коді відповідні перевірки на допустимість вхідних даних реальному
діапазону значень.
Кожна з написаних студентом програм повинна бути інтерактивною і на кожному
етапі свого виконання активно взаємодіяти з користувачем, інформуючи його про
6
необхідні вхідні дані, результати свого виконання і варіантах подальшої поведінки
користувача.
Програмний код написаних студентом лабораторних робіт не повинен містити
фрагменти, що не стосуються теми лабораторної роботи, варіанту завдання
лабораторної роботи або невживані фрагменти.
Рекомендації по створенню власних проектів в середовищі Visual Studio
Для того, щоб забезпечити безпомилкову компіляцію програми при використанні
зовнішніх функцій мови С і з використанням символів кирилиці кодової таблиці 1251 в
середовищі Windows студентам слід виконати наступні чотири дії для кожного свого
програмного проекта:
1. Використовувати наступну структуру програмного коду програми main() в своїх
лабораторних роботах:
#define _CRT_SECURE_NO_WARNINGS
#include "stdlib.h"
#include "stdio.h"
#include "conio.h"
#include "math.h"
#include "locale.h"
#include "string.h"
#include "windows.h"
…
<тип_значення_що_повертається> main (<список_параметрів>) {
<розділ_оголошень_програми>
…
<виконуване_тіло_програми_(код)>
…
}
2. Далі слід вказати курсором миші на ім'я проекту у вікні Solution Explorer, клацнути
правою клавішею миші і вибрати у випадаючому меню пункт "Properties". У вікні
властивостей, ліворуч, зробити наступний вибір:
"Configuration Properties" -> "General"
і на вкладці праворуч перейти до властивості "Character Set". В цій властивості,
за допомогою меню, що випадає встановити набір символів "Not Set".
7
3. Далі слід, вказавши курсором мишки на ім'я проекту у вікні Solution Explorer,
клацнути правою клавішею миші та обрати у випадаючому меню пункт
"Properties". У вікні властивостей зліва, зробити наступний вибір:
"Configuration Properties" -> "C/C++" -> "Pre-compiled headers"
і на вкладці праворуч перейти до властивості "Pre-compiled header". У цій
властивості, за допомогою меню, що випадає встановити режим "Do not use
precompiled headers".
4. У властивостях нового проекту для даних лабораторних робіт слід вказати явно
використання стандарту мови C++ при компіляції, що дозволить повноцінно
використовувати нові можливості С++ при написанні коду С. Для цього слід
вказати курсором мишки на ім'я проекту у вікні Solution Explorer, клацнути
правою клавішею миші і вибрати в меню, що випало, пункт "Properties". У вікні
властивостей, ліворуч, зробити наступний вибір:
Configuration Properties -> C/C++ -> Advanced
У правій частині вікна, що відкрилося, в рядку вибору "Compile as" вибрати
режим "Compile as C++ code (/ TC)" і натиснути внизу кнопку ОК. Виконати цю
процедуру для кожного проекту в рішенні.
8
ЛАБОРАТОРНА РОБОТА №1. АЛГОРИТМИ СОРТУВАННЯ
Мета роботи: Вивчити і реалізувати алгоритми внутрішнього сортування трьох
видів складності: O(N2), O(N*log(N)) та O(N). Розібратися з принципами побудови
алгоритмів сортування та їх подальшою реалізацією на мові процедурного
програмування Сі.
До виконання лабораторної роботи студенту слід ознайомитися з матеріалом
відповідного розділу "Сортування" [5]. Усі нижчеописані алгоритми здійснюють
сортування за збільшенням. При необхідності організувати сортування за зменшенням
– алгоритми слід відповідно (додаткове питання на захисті!) змінити.
// Функція отримує на вході несортований масив цілих чисел і повертає його вже
// отсортованим.
// Ім'я функції sortChoice повертає код завершення функції:
// 0 – функція виконалась успішно;
// 1 – невірний розмір масиву, сортування не відбулось.
9
/* Перевірка корректності розміру масиву */
if (n<1)
return 1;
10
Рис. 1.2.Б. Сортування підмасивів з одночасним злиттям
Складність методу злиття оцінюється як O(N*logN). Але об'єм пам'яті, яка буде
використана при цьому, дорівнює 2*N.
/* функція ділить вхідний масив на дві половини, потім викликає себе для ділення
масивів на наступні дві половини і так далі
Значення, що повертається функцією:
0 – сортування виконалось успішно:
1 – недостатньо пам'яті для виконання */
if (beg<end) {
mid = (beg+end)/2; // визначаємо серединку
sortMerge(arr, beg, mid); // сортуємо лівий та правий підмасиви
sortMerge(arr, mid+1, end); // об'єднуємо відсортовані підмасиви
if (!merge(arr, beg, mid, end))
return 0; // якщо все в порядку, повертаємо 0
else
return 1; // якщо нестача пам'яті, повертаємо 1
}
}
11
Лівий підмасив arr[beg..mid]
Правий підмасив arr[mid+1..end] */
12
for(k=beg;k<index;k++)
arr[k] = temp[k];
13
int compareIntegers(const void* first, const void* second) {
int a = *((int*)first), b = *((int*)second);
if (a == b) return 0;
else if (a < b) return -1;
else return 1;
}
14
}
return 0; // нормальне повернення з функціі – масив відсортований
}
1. Титульний лист.
2. Мета роботи та завдання.
3. Теоретичні відомості (необов'язково).
4. Схема алгоритму програми.
5. Оригінальний текст програми з коментарями.
6. Набори тестових значень з основними результатами (скрини екранів та текст).
7. Побудова трьох швидкісних графіків залежності часу сортування від розміру масиву
на одному малюнку.
8. Висновки по роботі.
15
1.7. Варіанти завдань
№
Завдання: три алгоритми сортування для реалізації
варіанта
16
№
Завдання: три алгоритми сортування для реалізації
варіанта
17
ЛАБОРАТОРНА РОБОТА №2. ЛІНІЙНІ АБСТРАКТНІ СТРУКТУРИ
ДАНИХ (АТД)
18
лише за прямими, але і за зворотними посиланнями, то в разі, якщо якесь із посилань
стане невірним, цілісність списку можна відновити за іншим посиланням.
Для ще більшої ефективності списку використовується наступна структура
дескриптора списку START:
• назва списку;
• покажчик (адреса) початку списку;
• покажчик (адреса) кінця списку;
• поточне число елементів списку;
• опис елемента (довжина, тип і т.п.).
Тобто, до дескриптора списку додається покажчик кінця списку (END). Для
відсортованих списків це дозволяє домогтися більшої ефективності пошуку. Алгоритми
для роботи з двонапрямленими і однонапрямленими списками дуже схожі, за винятком
того, що перші повинні виконувати додаткові дії для управління ще одним набором
посилань.
Детальний опис роботи алгоритмів обробки двонапрямлених списків наведено в
розділі 6.4 роботи [6]. При виконанні відповідного завдання лабораторної роботи
студент може взяти за основу програмну реалізацію алгоритмів, наведену в кінці цього
ж розділу (с.с. 194-198).
19
дозволить йому відразу-ж і запуститися.
Ще один приклад використання циклічного списку - це Інтернет. Коли ми працюємо
в Інтернеті, ми можемо використовувати кнопку Назад і кнопку Уперед для переходу до
попередніх / наступних сторінках, на яких ми вже раніше побували. Для цього циклічний
список використовується для підтримки послідовності відвіданих Web сторінок.
Алгоритми для роботи з циклічними списками повинні враховувати відсутність
термінальних вузлів в списку, для чого використовувати маркування вузлів списку. Це
ускладнює їх реалізацію.
Детальний опис роботи алгоритмів обробки циклічних списків наведено в розділі 6.3
роботи [6]. При виконанні відповідного завдання лабораторної роботи студент може
взяти за основу програмну реалізацію алгоритмів, наведену в кінці цього ж розділу (с.с.
184-187).
20
2.3. Вимоги до виконання роботи
1. Титульний лист.
2. Мета роботи та завдання.
3. Теоретичні відомості (необов'язково).
4. Схема алгоритму програми.
5. Оригінальний текст програми з коментарями.
6. Набори тестових значень з основними результатами (скрини екранів та текст).
7. Висновки по роботі.
21
Тип елементу структури Структура АТД, яку
Номер варіанту
даних вузла АТД потрібно реалізувати
Кільцевий
19 Точка в просторі R3
однонапрямлений список
20 Рядок Однонапрямлений список
21 Комплексне число Однонапрямлений список
22 Дійсне число Двонапрямлений список
Кільцевий
23 Рядок
однонапрямлений список
24 Комплексне число Стек
25 Точка в просторі R3 Стек
26 Ціле число Двонапрямлений список
Кільцевий
27 Дійсне число
однонапрямлений список
28 Рядок Черга
29 Комплексне число Двонапрямлений список
Кільцевий
30 Точка в просторі R3
однонапрямлений список
1. Скільки полів може містити вузол списку? Від чого залежить кількість полів?
Наведіть приклади.
2. Якого типу можуть бути поля вузлів списку? Наведіть приклади.
3. Чи обов'язково застосовувати процедуру звільнення пам'яті, зайнятої вузлом,
коли ми позбавляємося від цього вузла в списку? Яким чином це впливає на
роботу програми?
4. Чи може вузол списку бути такого типу, щоб утримувати кілька полів типу
покажчика? Якщо - так, то наведіть приклад для чого це може бути потрібно.
5. Чи можна одночасно працювати з декількома списками відразу?
6. Як Ви вважаєте, на що потрібно звертати особливу увагу при роботі зі
списками?
7. Поняття двонапрямленого списку. Які можливі структури двонапрямленого
списку?
8. Як задавати двонапрямлений список?
9. Які основні операції над двонапрямленим списком?
10. Що таке АТД стек та черга?
11. Як представляються в пам'яті АТД стек та черга?
12. Які основні операції над АТД стек та черга?
13. У чому полягають відмінності між АТД стек та черга?
14. Переваги та недоліки різного представлення (списком, масивом) в пам'яті
АТД стек та черга.
15. Що таке кільцевий список? Представлення АТД кільцевий список у пам'яті.
16. В чому полягають відмінності при роботі з кільцевим списком та
двонапрямленим чи однонапрямленими списками?
22
ЛАБОРАТОРНА РОБОТА №3. БІНАРНІ ДЕРЕВА
Мета роботи: Вивчити принципи побудови абстрактних типів даних типу бінарне
дерево та алгоритми їх обробки мовою процедурного програмування Сі. До виконання
лабораторної роботи студенту слід ознайомитися з матеріалом відповідних розділів
теми "Дерева" [5]
23
3.2.1. Обхід в прямому порядку
1. Пройти D.
2. Вивести D.
3. Пройти B.
4. Вивести B.
5. Пройти A.
6. Вивести A.
7. Пройти B.
8. Пройти C.
9. Вивести C.
10. Пройти B.
11. Пройти D.
12. Пройти E.
13. Вивести E.
14. Пройти D.
24
Приклад 3.2 Алгоритм прямого обходу бінарного дерева
typedef struct BTnode {
struct BTnode *left;
int data;
struct BTnode *right;
};
1. Пройти D.
25
2. Пройти B.
3. Пройти A.
4. Вивести A.
5. Пройти B.
6. Вивести B.
7. Пройти C.
8. Вивести C.
9. Пройти B.
10. Пройти D.
11. Вивести D.
12. Пройти E.
13. Вивести E.
14. Пройти D.
26
до правої дочірньої вершини E. Не виявивши пов'язаних з нею нащадків,
алгоритм зразу виведе E і повернеться до D. Раз обхід дочірніх вершин
закінчено, залишається вивести D і завершити траверс. В цілому порядок
проходження алгоритму буде таким: A, C, B, E, D.
У наступному списку представлені кроки, які виконуються під час
зворотного обходу для дерева, зображеного на Рис. 3..
1. Пройти D.
2. Пройти B.
3. Пройти A.
4. Вивести A.
5. Пройти B.
6. Пройти C.
7. Вивести C.
8. Пройти B.
9. Вивести B.
10. Пройти D.
11. Пройти E.
12. Вивести E.
13. Пройти D.
14. Вивести D.
27
поточному рівні в порядку зліва направо, а потім переходить до вершин
наступного рівня. У випадку з деревом, зображеним на Рис. 3., програма
насамперед звернеться до кореня і виведе D, потім перейде до наступного рівня
і виведе вершини B і E, а на завершальному етапі опуститься на нижній рівень і
виведе A і С. Повний обхід буде виглядати так: D, B, E, A, C.
Цей алгоритм також називають BFT (breadth-first traversal) алгоритмом
обходу. Даний алгоритм не дотримується структури дерева, на відміну від
алгоритмів, розглянутих вище. У використовуваному прикладі немає дочірньої
гілки від вершини E до вершини A, тому неясно, як алгоритм до неї перейде.
Щоб вирішити це завдання, потрібно додати дочірні вершини в чергу (яку
створюємо додатково!), а потім обробити їх, коли завершиться обробка
батьківського рівня.
Приклад такого алгоритму на мові Сі наведено нижче:
Приклад 3.5 Алгоритм обходу бінарного дерева в ширину
typedef struct tQueueNode { /* структура вузла черги */
BTnode data; /* дані елемента черги - вершини дерева */
tQueueNode *next;
};
tQD *dsChildren;
BTnode *node;
28
// Створюємо чергу для зберігання дочірніх вершин при подальшій обробці.
dsChildren = CreateQueue();
if (!dsChildren) return -1; /* немає пам'яті в купі */
29
Рис. 3.3 Доступ до дерева за допомогою дескриптора
У найпростішому випадку дескриптор не використовується, доступ до
дерева здійснюється за покажчиком, оголошеному в програмі як змінна.
Алгоритм створення бінарного дерева зводиться до створення і ініціалізації
дескриптора. На мові Сі це виглядає так:
Приклад 3.6 Алгоритм створення бінарного дерева
typedef struct BTnode { /* вершина дерева */
struct BTnode *left;
int data;
struct BTnode *right;
};
30
бінарне дерево пошуку порожнім. Якщо воно порожнє, то значення, яке ми
шукаємо відсутнє в дереві. Таким чином, алгоритм пошуку завершується
шляхом повернення значення NULL в якості знайденої вершини до програми,
що викликала. Якщо ж є вершини в дереві, то алгоритм перевіряє, чи є ключове
значення поточної вершини рівним значенню пошуку. Якщо ТАК, алгоритм
повертає в викликану програму адресу знайденої вершини і завершується. Якщо
НІ, то алгоритм перевіряє, чи є значення для пошуку меншим, ніж значення
поточної вершини, і в цьому випадку він повинен рекурсивно викликати сам
себе з лівої дочірньої вершини в якості параметра. У разі, якщо значення пошуку
більше, ніж значення ключа поточної вершини, алгоритм повинен рекурсивно
викликати себе з правої дочірньої вершини.
Алгоритм пошуку на мові Сі може виглядати так:
Приклад 3.7 Алгоритм пошуку в бінарному дереві пошуку
typedef struct BTnode { /* вершина дерева */
struct BTnode *left;
int data;
struct BTnode *right;
};
31
Рис. 3.5 Приклад вставки ключа 42 у бінарне дерево пошуку
32
else if (key < subTree -> data)
tempNode = insertTree(dsTree, subTree -> left, key);
return tempNode;
}
33
Рис. 3.7 Видалити вершину 5 з бінарного дерева пошуку
34
по лівим гілкам. Оскільки у знайденому мінімуму немає лівого сина, можна
вирізати його за аналогією з випадком 1 і вставити його замість видаляємої
вершини. Через те що він був мінімальним в правому піддереві, властивість
впорядкованості не порушується:
35
if (!subTree)
return (subTree);
else if (current -> left == NULL && current -> right == NULL) {
// якщо вершина, що видаляється стоїть зліва від батьківської
if (parent -> left == current)
parent - > left = NULL;
// якщо справа від батьківської
else
parent -> right = NULL;
temp = current;
dsTree -> size--;
free (current);
return temp;
}
36
3.7. Видалення бінарного дерева
37
3.9. Вимоги до виконання роботи
1. Титульний лист.
2. Мета роботи та завдання.
3. Теоретичні відомості (необов'язково).
4. Схеми алгоритмів обробки дерева.
5. Оригінальний текст програми з коментарями.
6. Набори тестових значень з основними результатами (скрини екранів та текст).
7. Висновки по роботі.
38
основні поняття, пов'язані з бінарним деревом
3. Які способи обходу бінарного дерева ви знаєте?
4. У чому полягає особливість бінарних дерев пошуку?
5. Для яких цілей застосовуються бінарні дерева? Які види бінарних
дерев ви знаєте?
6. Як бінарні дерева представляються у пам'яті ЕОМ?
7. Як здійснюється вставка і видалення елемента бінарного дерева
пошуку?
8. Як здійснюється створення і видалення бінарного дерева?
9. Як здійснюється пошук елемента в бінарному дереві?
39
ЛАБОРАТОРНА РОБОТА №4. АЛГОРИТМИ І ПРИНЦИПИ
ХЕШУВАННЯ. РОЗВ'ЯЗАННЯ КОЛІЗІЙ
Мета роботи:
– вивчити особливості організації хеш-таблиць для різних типів алгоритмів
хешування;
– отримати практичні навички використання функцій рехешування для
розширення колізій в хеш-таблицях;
– створити консольний додаток, в якому реалізовані операції вставки,
видалення і пошуку елементів в хеш-таблиці.
40
Структура самої хеш-таблиці для розглянутого прикладу приведена на рисунку нижче:
Таблиця 4.1
Індекс Ключ (код деталі) Запис
0 4967000
1 6584001
2 8421002
...
396 4618396
397 4759397
398 9572398
399 1286399
...
990 0000990
991 0000991
992 1200992
993 0047993
...
998 5682998
999 0001999
41
занадто близьким до степеня числа 2. Тому що у цьому випадку функція буде просто
видавати молодші K біт двійкового представлення ключа K.
42
різних ключів можуть збігатися. Наприклад, при додаванні в Таблиця 4.1, наведену
вище, запису з ключем 0596998 виникне така ситуація, що дана комірка вже зайнята.
Ситуація, коли два або більше ключа асоціюються з однією і тією ж коміркою
таблиці називається колізією при хешуванні. Слід зазначити, що гарною хеш-
функцією є така функція, яка мінімізує колізії і розподіляє записи рівномірно по всій
таблиці.
Для вирішення проблеми колізій необхідно визначити:
якого виду хеш-функцію потрібно використовувати, щоб зменшити
число колізій?
що робити в разі виникнення колізій?
використовувати іншу хеш-функцію або послідовність функцій;
використовувати додаткову структуру даних (найчастіше
упорядкований список), в якому розміщуються всі елементи множини за
ключами, які претендують на один і той самий індекс.
Зазначені два підходи вирішення колізій відображаються в різних типах
алгоритмів хешування. Існує дві різні форми хешування. Одна з них називається
відкритою, або зовнішнім хешуванням і дозволяє зберігати множини в потенційно
нескінченному просторі, знімаючи тим самим обмеження на розмір множин. Інша
називається закритою, або внутрішнім хешуванням і використовує обмежений розмір
пам'яті для зберігання даних, обмежуючи таким чином розмір елементів хеш-масиву.
Алгоритми хешування цих двох способів наведено у відповідному розділі [5].
43
стану структури даних на консоль (у файл).
5. Число елементів у хеш-таблиці повинно бути змінним, але не меншим від 20.
Передбачити, що заповнення елементів хеш-таблиці проводити за
допомогою генератора випадкових чисел, чи вручну (для тестування).
6. Зробити висновки по роботі.
1. Титульний лист.
2. Мета роботи та завдання.
3. Теоретичні відомості (необов'язково).
4. Схеми алгоритмів обробки хеш-таблиці.
5. Оригінальний текст програми з коментарями.
6. Набори тестових значень з основними результатами (скрини екранів та текст).
7. Висновки по роботі.
У якості структури (типу) даних, що буде зберігатися у хеш-таблиці, слід взяти тип
даних та ключ, який використовувався у 3 лабораторній роботі. При використанні у
якості ключа символьного рядку – використовувати функцію хешування, описану у п.
4.3.4, при використанні у якості ключа числового цілочисельного значення –
використовувати у якості функції хешування метод середини квадрата (п. 4.3.3).
Таблиця 4.2
Варіант Алгоритм Функція Початковий Розмір
хешування пробірування розмір блоку
хештаблиці розширення
метод
1 - 100 -
ланцюжків
відкрита
2 лінійна 10 15
адресація
метод
3 - 100 -
ланцюжків
44
Варіант Алгоритм Функція Початковий Розмір
хешування пробірування розмір блоку
хештаблиці розширення
відкрита
4 квадратична 10 10
адресація
метод
5 - 100 -
ланцюжків
відкрита подвійне
6 10 13
адресація хешування
метод
7 - 100 -
ланцюжків
відкрита
8 лінійна 10 13
адресація
метод
9 - 100 -
ланцюжків
відкрита
10 квадратична 10 14
адресація
метод
11 - 120 -
ланцюжків
відкрита подвійне
12 12 12
адресація хешування
метод
13 - 120 -
ланцюжків
відкрита
14 лінійна 12 16
адресація
метод
15 - 120 -
ланцюжків
відкрита
16 квадратична 12 17
адресація
метод
17 - 120 -
ланцюжків
відкрита подвійне
18 12 20
адресація хешування
метод
19 - 12 -
ланцюжків
відкрита
20 квадратична 12 18
адресація
відкрита
21 квадратична 10 14
адресація
метод
22 - 100 -
ланцюжків
45
Варіант Алгоритм Функція Початковий Розмір
хешування пробірування розмір блоку
хештаблиці розширення
відкрита
23 лінійна 10 13
адресація
метод
24 - 100 -
ланцюжків
відкрита подвійне
25 10 13
адресація хешування
метод
26 - 100 -
ланцюжків
відкрита
27 квадратична 10 10
адресація
метод
28 - 100 -
ланцюжків
відкрита
29 лінійна 10 15
адресація
метод
30 - 100 -
ланцюжків
1. Що записується в хеш-таблицю?
2. Чим визначається індекс запису в хеш-таблиці?
3. Які основні проблеми хешування і в чому вони полягають?
4. Скільки операцій порівняння виконується при пошуку по ключу із
застосуванням таблиць прямого доступу?
5. Які недоліки алгоритма пошука по ключу з використанням відкритої
адресації?
6. Яке призначення хеш-функції?
7. Назвіть базові функції хешування.
8. Як створюється хеш-таблиця при реалізації метода відкритої адресації? Що
зберігається в елементах такої хеш-таблиці?
9. Назовіть алгоритми розв’язку колізій при відкритій адресації.
10. В чому суть метода розв’язку колізій при використанні розподілених ланцюгів
переповнень?
46
РЕКОМЕНДОВАНА ЛІТЕРАТУРА
Базова
Допоміжна
6. Thareja R. Data Structures Using C, 2nd Edition. - New Delhi: Oxford University Press,
2014. – 557 p.
7. Bhasin H. Algorithms. Design and Analysis. - New Delhi: Oxford University Press,
2015. – 727 p.
8. Головешкин В.А., Ульянов М.В. Теория рекурсии для программистов. - М.:
ФИЗМАТЛИТ, 2006. - 296 с.
9. Ворожцов А.В. Алгоритмы, анализ, построение и реализация на языке Си:
Лекции. – Москва: МФТИ, 2007. – 452 с.
10. Хэзфилд Р., Кирби Л. Искусство программирования на Си. Фундаментальные
алгоритмы, структуры данных и примеры приложений: Энциклопедия
программиста. – Киев: Диасофт, 2001. – 736 с.
11. Клейнберг Дж., Тардос Е. Алгоритмы. Разработка и применение. - СПб.: Питер,
2016. — 800 с.
12. Кормен Т.Х. Алгоритмы: вводный курс. — М.: ООО “И.Д. Вильямс”, 2014. — 208
с.
13. Скиена С. Алгоритмы. Руководство по разработке, 2-е изд. — СПб.: БХВ-
Петербург, 2011. — 720 с.
14. Tiwari N.K., Agrawal J., Shandilya Sh.K. DATA STRUCTURES. - New Delhi: I.K.
International Publishing House Pvt. Ltd., 2016. – 275 p.
15. Алексеев В.Е., Таланов В.А. Графы. Модели вычислений. Структуры данных:
Учебник. – Нижний Новгород: Изд-во ННГУ, 2005. 307 с.
16. Валединский В.Д., Пронкин Ю.Н. Вычислительные системы и
программирование. Схемы хранения данных. – Москва: Изд-во ЦПИ при
механико-математическом факультете МГУ, 2006. – 168 с.
47
Додаткова література, видана на українській мові
48
ДОДАТОК 1. ВИМОГИ ДО ОФОРМЛЕННЯ КОДУ ПРОГРАМ НА МОВІ СІ
Угоди по ідентифікаторам
Підбір ідентифікаторів
Написання ідентифікаторів
49
А. У будь-якому ідентифікаторі кожне слово, що входить в ідентифікатор, писати,
починаючи з великої літери, інші літери - маленькі.
Наприклад:
float NextX, LastX; // Наступна і попередня ітерація
char BeepOnError; // Звуковий сигнал при
// неправильних діях користувача
unsigned char FileName [20];
Б. У будь-яких ідентифікаторах кожне слово, що входить в ідентифікатор, розділяти
символом _, при цьому всі букви - маленькі.
Наприклад:
float next_x, last_x; // Наступна і попередня ітерація
char beep_on_error; // Звуковий сигнал при
// неправильних діях користувача
unsigned char file_name [20];
В. Для ідентифікаторів імен функцій прийнято використовувати перше слово
ідентифікатора з маленької літери, а усі наступні – з великої. Символ _ при цьому не
застосовується.
Наприклад:
// Стандартна функція модуля Graph; видає опис
// помилки використання графіки по її коду
unsigned char * graphErrorMsg (short err_code);
Г. Усі літери ідентифікаторів макросів, макровизначень у програмі прийнято писати
використовуючи виключно великі літери.
Наприклад:
#define SIZE 100
#define ABS(x) ((x)<0?-(x):(x))
…
…
double Arr(SIZE);
…
…
c = ABS(a-b);
Коментарі
50
Специфікація функцій
Примітка:
51
Якщо функція реалізує будь-який обчислювальний метод (наприклад: знаходження
площі фігури методом трапецій, пошук мінімуму функції методом Ньютона і т.і.),
рекомендується в тілі функції розмістити коментар з коротким описом методу, або
посилання на джерело, де описаний метод.
"Драбинка"
if ( <умова> )
<оператор>;
52
if ( <умова> ) {
<оператори>
}
else {
<оператори>
}
while ( <умова> ) {
<операторы>
}
while ( <умова> )
<оператор>;
switch ( <вираз> ) {
case <вираз>:
<оператори>;
break;
........
default:
<оператори>;
}
float D;
D = sqr( B ) -4 * A * C;
53
if ( D < 0 ) {
*Num = 0;
*X1 = 0;
*X2 = 0;
}
else {
*X1 = ( -B + sqrt( D ) ) / ( 2 * A );
*X2 = ( -B - sqrt( D ) ) / ( 2 * A );
if ( *X1 == *X2 )
*Num = 1;
else
*Num = 2;
}
}
Інші рекомендації
54
printf ( "багато!");
}
55