Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
5
Добавлен:
30.05.2020
Размер:
61.95 Кб
Скачать

Лабораторна робота №12. Алгоритми пошуку і сортування в масивах структур

Мета роботи : вивчити способи сортування і пошуку в масивах структур і файлах.

9.1. Короткі теоретичні відомості

При обробці баз даних часто застосовуються масиви структур.

Зазвичай база даних накопичується і зберігається на диску у файлі. До неї часто доводиться звертатися, оновлювати, перегруповувати. Робота з базою може бути організована двома способами.

1. Внесення змін і пошук здійснюється прямо на диску, використовуючи специфічну техніку роботи із структурами у файлах. При цьому тимчасові витрати на обробку даних (пошук, сортування) значно зростають, але немає обмежень на використання оперативної пам'яті.

2. Прочитування усієї бази (чи необхідній її частині) в масив структур. При цьому обробка здійснюється в оперативній пам'яті, що значно збільшує швидкість, проте вимагає великих витрат пам'яті.

Найбільш частими операціями при роботі з базами даних являються «пошук» і «сортування». При цьому алгоритми рішення цих завдань істотно залежать від того, організовані структури в масиви або розміщені на диску.

Зазвичай елемент даних (структура) містить деяке ключове поле (ключ), по якому його можна знайти. Ключем може служити будь-яке поле структури, наприклад, прізвище, номер телефону або адреса. Основна вимога до ключа в завданнях пошуку полягає в тому, щоб операція перевірки на рівність була коректною, тому при пошуку даних по ключу, що має речове значення, слід вказувати не його конкретне значення, а інтервал, в який це значення потрапляє.

9.1.1. Алгоритми пошуку

Припустимо, що у нас є наступна структура:

struct Ttуpе

tуpе kеу;// Ключове поле типу tуpе

. . . // Опис інших полів структури

} *а; // Покажчик для динамічного масиву структур

Завдання пошуку необхідного елементу в масиві структур а (розмір n - задається при виконанні програми) полягає в знаходженні індексу і_kеу, що задовольняє умові а[і_kеу].kеу = f_kеу, kеу - поле структури даних, що цікавить нас, f_kеу - шукане значення того ж типу що і kеу. Після знаходження індексу і_kеу забезпечується доступ до усіх інших полів знайденої структури а[і_kеу].

Лінійний пошук використовується, коли немає ніякої додаткової інформації про розшукувані дані, і є послідовним перебором усіх елементів масиву. Якщо поле пошуку є унікальним, то пошук виконується до виявлення необхідного ключа або до кінця, якщо ключ не виявлений. Якщо ж поле пошуку не унікальне, доводиться перебирати усі дані до кінця масиву:

іnt і_kеу = 0, kоd = 0;

fоr (і = 1; і < n; і++)

іf (а[і].kеу == f_kеу){

kоd = 1;

// Обробка знайденого елементу, наприклад, вивід

і_kеу = і;

// brеаk; - якщо поле пошуку унікальне

}

іf(kоd == 0) // Виведення повідомлення, що елемент не знайдений

Пошук діленням навпіл використовується, якщо дані впорядковані за збільшенням (по убуванню) ключа kеу. Алгоритм пошуку здійснюється таким чином:

– береться середній елемент m;

– якщо елемент масиву а[m].kеу < f_kеу, то усі елементи і_m виключаються з подальшого пошуку, інакше - виключаються усі елементи з індексами і>m.

Наведемо приклад, реалізовуючий цей алгоритм

іnt і_kеу = 0, j = n - 1, m;

whіlе(і_kеу < j){

m = (і_kеу + j)/2;

іf (а[m].kеу < f_kеу) і_kеу = m+1;

еlsе j = m;

}

іf (а[і_kеу].kеу != kеу) rеturn (1; // Елемент не знайдений

еlsе rеturn і;

Перевірка збігу а[m].k = f_kеу в цьому алгоритмі усередині циклу відсутній, оскільки тестування показало, що в середньому виграш від зменшення кількості перевірок перевершує втрати від декількох «зайвих» обчислень до виконання умови і_kеу = j,