- •1.1. Визначення інформації
- •1.2. Визначення алгоритму
- •1.3. Виконавці алгоритмів
- •1.4. Способи описання алгоритмів
- •1.5. Властивості алгоритмів
- •1.6. Поняття обчислювальної складності
- •1.7. Класи алгоритмів
- •1.7.1. Експоненційні алгоритми та перебір
- •1.7.2. Алгоритм із поверненнями назад
- •1.7.3. Машини Тьюринґа
- •Будь-який алгоритм може бути реалізований відповідною машиною Тьюринґа.
- •Усе, що реалізовано в одній з цих конструкцій, можна зробити і в інших.
- •1.7.4. Рекурсія та її використання
- •1.7.5. Теза Чорча. Алгоритмічно нерозв’язні проблеми
- •2.1. Поняття структури даних
- •2.2. Рівні описуваннявання даних
- •2.3. Класифікація структур даних у програмах користувача й у пам’яті комп’ютера
- •2.4. Основні види складених типів даних
- •2.4. Структури даних у пам’яті комп’ютера
- •2.4.1. Структури даних в оперативній пам’яті
- •2.4.2. Сд у зовнішній пам’яті
- •3.1. Поняття структури даних типу «масив»
- •3.2. Набір допустимих операцій для сд типу «масив»
- •3.3. Дескриптор сд типу «масив»
- •3.4. Ефективність масивів
- •3.5. Зберігання багатовимірних масивів
- •3.6. Сд типу «множина»
- •3.7. Сд типу «запис (прямий декартовий добуток)»
- •3.8. Сд типу «таблиця»
- •3.9. Сд типу «стек»
- •3.9.1. Дескриптор сд типу «стек»
- •3.9.2. Області застосування сд типу «стек»
- •3.10. Сд типу «черга»
- •3.11. Сд типу «дек»
3.8. Сд типу «таблиця»
Таблиця – послідовність записів, які мають ту саму організацію. Такий окремий запис називається елементом таблиці. Найчастіше використовується простий запис. Отже, таблиця – це аґреґація елементів. Якщо послідовність записів впорядкована щодо певної ознаки, то така таблиця називається впорядкованою, інакше – таблиця невпорядкована.
Класифікацію СД типу таблиця подано на рис. 3.1.
Рис. 3.1. Класифікція СД типу «таблиця».
Якщо один елемент di , то кортеж – це <d1, d2, …, dn>, причому DTi di. Множина значень елементів типу Т (множина допустимих значень СД типу «таблиця») буде визначатися за допомогою прямого декартового добутку:
DT = DT1 DT2 … DТn, причому DTi <d1, d2, …, dn>…
Сам елемент таблиці можна подати у вигляді двійки <K, V>, де К – ключ, а V – тіло елемента. Ключем може бути різна кількість полів, які визначають цей елемент. Ключ використовується для операції доступу до елемента, тому що кожний із ключів унікальний для заданого елемента. Отже, таблиця є сукупністю двійок <K, V>.
На логічному рівні елемент СД типу «таблиця» описуванняється так (приклад на мові Паскаль):
Type Element = record
Key: integer;
{опис інших полів}
end;
При реалізації таблиці як відображення на масив її опис виглядає так:
Tabl = array [0 .. N] of Element.
Під час виконання програми кількість елементів може змінюватися. Структура, у якій змінюється кількість елементів під час виконання програми, називається динамічною. Якщо розглядати динамічну структуру як відображення на масив, то така структура називається напівстатичною.
Перед тим як визначити операції, які можна виконувати над таблицею, розглянемо класифікацію операцій.
Конструктори – операції, які створюють об’єкти розглянутої структури.
Деструктори – операції, які руйнують об’єкти розглянутої структури. Ознакою цієї операції є звільнення пам’яті.
Модифікатори – операції, які модифікують відповідні структури об’єктів. До них належать динамічні й напівстатичні модифікатори.
Спостерігачі – операції, у яких елементом (вхідним параметром) є об’єкти відповідної структури, а повертають ці операції результати іншого типу. Отже, операції-спостерігачі не змінюють структуру, а лише подають інформацію про неї.
Ітератори – оператори доступу до вмісту частини об’єкта у певному порядку.
Набір допустимих операцій для СД типу «таблиця» подаємо нижче
Операція ініціалізації (конструктор).
Операція включення елемента в таблицю (модифікатор).
Операція виключення елемента з таблиці (модифікатор).
Операції-предикати:
таблиця порожня / таблиця не порожня (спостерігач),
таблиця переповнена / таблиця не переповнена (спостерігач).
Читання елемента за ключем (спостерігач).
3.9. Сд типу «стек»
Стек – це послідовність, у якій включення й виключення елемента здійснюється з однієї сторони послідовності (вершини стека). Так само здійснюється й операція доступу. Структура функціонує за принципом LIFO (останній, що прийшов, обслуговується першим). Умовні позначення стека зображені на рис 3.2.
а) відображеня на масив б) відображення на список
Рис. 3.2. Організація стека.
При реалізації стека розглядаються стек як відображення на масив і стек як відображення на список.
Відображення на масив передбачає оголошення звичайного масиву та змінної, значення якої дорівнюватиме значенню індексу елемента, що відіграватиме роль «голови» (елемента, на який вказуватиме вказівник):
int a[100]; // оголошення стеку
int n=0; // дійсна кількість елементів у стека
int current=99; // індекс «голови», діє принцип LIFO
void pop () // функція видобування (вилучення) елемента зі стека
{
if (n!=0)
{ current++; // зсунули «голову» на один елемент вперед
printf(“%d%, a[current]);
n--; } // зменшили кількість елементів
}
void push () // функція додавання елемента до стеку
{
if (n<99)
{ current--;
//додали «голову», зсунувши індекс на один елемент вперед
scanf(“%d%, &a[current]);
n++; } // збільшили кількість елементів
}
Відображення на список передбачає оголошення динамічної структури. Перевагою такого відображення є відсутність обмежень на максимальну кількість елементів у стеку, але, водночас, передбачає підтримку складнішої вказівникової структури:
struct stack {
int el; // значення елемента
struct stack *next;} st // адреса наступного елемента
st *head, *p1, *p2; //вказівник на «голову», допоміжні вказівники
st* push(int a; st *cur)
// функція додавання елемента,
// а – значення, яке треба внести у стек
// cur – вершина («голова») стека
{ st *p;
// якщо стек порожній
if(!cur)
{
// створюємо вершину
cur=(st*)malloc(sizeof(st));
cur->el=a;
cur->next=NULL;
return(cur);
}
else
{
// створюємо новий елемент, який стане вершиною стека
p=(st*)malloc(sizeof(st));
p->el=a;
p->next=cur;
return(p);
}
}
st* pop() // видалення вершини стека
{ st *p;
if(head) // якщо в стеку є елементи
{ .// вершиною стає наступний елемент
p=head->next;
// знищуємо «голову»
free(head);
return(p);
}
else return (NULL);
}
Сукупність операцій, що визначають структуру типу «стек», подана нижче.
Операція ініціалізації.
Операція включення елемента в стек.
Операція виключення елемента зі стека.
Операція перевірки: стек порожній / стек не порожній.
Операція перевірки: стек переповнений / стек не переповнений (ця операція характерна для стека як відображення на масив).
Операція читання елемента (доступ до елемента).
Є дві модифікації стека:
вказівник перебуває на вершині стека, показуючи на перший порожній елемент;
в
слот
казівник вказує на перший заповнений елемент.