- •Історична довідка
- •Характеристика й особливості мови
- •Алфавіт мови
- •Службові (зарезервовані) слова.
- •Структура програми мови Turbo Pascal
- •Розділ оголошень і угод
- •Розділ текстів процедур і функцій
- •Розділ основного блоку програми
- •Процедури введення-виведення. Деякі вбудовані функції Турбо-Паскаля.
- •Функції числових параметрів.
- •Базові управляючі конструкції Турбо-Паскаля Оператори умовного переходу.
- •1. Оператор if.
- •2. Оператор вибору (case)
- •Оператори циклів у Паскалі
- •1. Цикл із післяумовою (Repeat)
- •2. Цикл із предумовою (While)
- •3. Цикл із лічильником або параметром (For)
- •Концепція типів даних. Типи даних в мові Pascal
- •Дійсні типи
- •Бульовий (логічний) тип
- •Символьні і рядкові змінні
- •1. Символьний тип
- •2. Рядковий тип
- •Перерахований та обмежений типи
- •1. Перерахований тип
- •2. Обмежений тип
- •1. Поняття масиву. Одномірні масиви
- •2. Багатомірні масиви
- •3. Сортування і пошук
- •Множинний тип
- •Тип запис
- •Процедури і функції
- •Формальні і фактичні параметри. Механізм параметрів
- •Параметри - значення
- •Параметри-змінні
- •Безтипові параметри
- •Приведення типів.
- •Процедурні типи
- •Рекурсія Рекурсивні визначення
- •Рекурсивні підпрограми
- •Алгоритми з поверненням. Розв’язок задачі про рух коня
- •Алгоритми з поверненням. Розв’язок задачі про вісьмох ферзів
- •If підходить тнеn
- •Модулі в Турбо Паскалі
- •Модуль crt
- •1. Керування екраном
- •2. Робота з клавіатурою
- •3. Інші можливості
- •Графіка в Турбо Паскалі
- •1. Включення і вимикання графічного режиму.
- •2. Побудова елементарних зображень
- •3. Виведення текстової інформації.
- •Файли в мові програмування Pascal
- •Установчі і завершальні операції
- •Операції введення-виведення
- •Обробка помилок введення-виведення
- •Переміщення по файлу
- •Спеціальні операції
- •Текстові файли
- •1. Оголошення файлової змінної і прив'язка до файлу на диску
- •2. Читання даних з файлу
- •3. Запис даних у файл
- •Двійкові файли
- •1. Типізовані файли
- •2. Нетипізовані файли
- •Статичні і динамічні змінні
- •Покажчики
- •Стан покажчика
- •Установка розмірів динамічної пам'яті
- •Сумісність і перетворення посилкових типів
- •Динамічні структури даних
- •Динамічні змінні: інші види списків, стек і черга.
- •1. Інші види списків
- •2. Стек і черга
- •Дерева і пошук у деревах
- •1. Визначення й описи структур даних
- •1. Масив
- •2. Список
- •3. Дерево
- •2. Алгоритми
- •1. Лінійний пошук у масиві
- •2. Двійковий пошук
- •3. Лінійний пошук у списку
- •Змішані таблиці
- •Об’єктно-орієнтоване програмування. Що таке об’єктно-орієнтоване програмування
- •Інкапсуляція
- •Спадкування
- •Віртуальні методи і поліморфізм
- •Конструктори, динамічні об'єкти і деструктори
- •Поля і методи: сховані і загальнодоступні
- •Системно- залежні розширення
- •Налагодження змінних
- •Оверлеї
- •Переривання і системні виклики
- •Доступ до пам'яті і портів
- •Перевизначення переривань
2. Список
Цей варіант більш економічний у плані витрати пам'яті, тому що завжди буде зайнято рівно стільки місця, скільки потрібно під дані. На відміну від масиву, ми не можемо легко переглядати дані довільного елемента, для переходу від одного елемента до іншого потрібно довго рухатися по ланцюжку покажчиків; це є недоліком списку.
Як виглядає така таблиця на Паскалі нам уже відомо:
type tItemPtr = ^tItem; {покажчик на елемент списку}
tItem = record {елемент списку}
key: tKey;
data: tData;
next: tItemPtr;
end;
tList: tItemPtr; {задається покажчиком на перший елемент}
var Table: tList {таблиця є списком}
3. Дерево
Як зберігати і шукати дані в двійковому дереві, ми вже знаємо, а таблицю можна задати так:
type tItemPtr = ^tItem; {покажчик на елемент}
tItem = record {елемент}
key: tKey;
data: tData;
left, right: tItemPtr;
end;
tTree = tItemPtr;
var Table: tTree; {таблиця є деревом}
2. Алгоритми
1. Лінійний пошук у масиві
Нехай таблиця представлена у виді масиву. Тоді перше, що приходить у голову з приводу пошуку елемента — це обхід всіх елементів, починаючи з першого, доти, поки не буде знайдений елемент із шуканим ключем, чи поки масив не скінчиться. Такий спосіб називається лінійним пошуком у неупорядкованому масиві. Оформимо його на Паскалі у виді процедури:
procedure LinearSearch(var T:tTable; k:tKey;var index:integer);
var i: integer;
begin
i:=1; index:=0;
while (i<=T.n)and(index=0) do begin
if T.a[i].key=k then index:=i;
i:=i+1;
end;
end;
Розглянемо докладніше частини цієї процедури. Параметрами процедури є таблиця (T), у якій потрібно шукати елемент, шукане значення ключа (k) і вихідний параметр (index), у якому процедура повинна вказати номер елемента, якщо він знайдений, і 0 у противному випадку. У списку параметрів таблиця T описана як параметр змінна, хоча процедура і не повинна змінювати які-небудь дані з таблиці. Це потрібно для того, щоб не створювати копію таблиці в стеці при передачі параметра процедурі, оскільки таблиця може мати великий розмір.
Можливий більш раціональний варіант: замість того щоб усякий раз перевіряти, чи не закінчився масив, можна використовувати масив з фіктивним елементом номер 0, перед пошуком записувати в нього шукане значення ключа, і рухатися по масиву від останнього елемента до першого. Такий спосіб називається лінійним пошуком з бар'єром (бар'єр — нульовий елемент):
procedure LinearSearch2(var T:tTable; k:tKey; var index:integer);
var i: integer;
begin
T.a[0]:=k;
index:=T.n; index:=0;
while T.a[index]<>k do index:=index-1;
end;
У такому варіанті стає значно менше порівнянь, отже, алгоритм працює швидше попереднього.
2. Двійковий пошук
Наступний алгоритм також застосовується для таблиці, представленої у виді масиву, крім того, масив повинний бути відсортованим за значеннями ключа (для визначеності — по зростанню). Тоді при пошуку можна використовувати наступні розуміння: візьмемо елемент, що знаходиться в середині масиву, якщо його ключ дорівнює шуканому ключу, то ми знайшли потрібний елемент, якщо менший — продовжуємо пошук у першій половині масиву, якщо більший — то в другий. Під продовженням розуміємо аналогічний процес: знову беремо середній елемент з обраної половини масиву, порівнюємо його ключ із шуканим ключем, і т.д. Цей цикл закінчиться, коли частина масиву, у якій виконується пошук, не буде містити жодного елемента. Тому що цей алгоритм багаторазово розбиває масив на дві частин, його називають алгоритмом двійкового пошуку. Нижче приведена відповідна процедура на Паскале.
procedure BinarySearch(var T:tTable; k:tKey; var index:integer);
var l,c,r: integer;
begin
index:=0;
l:=1; r:=T.n;
while (index=0)and(l<=r) do begin
c:=(l+r) div 2;
if T.a[c].key=k then index:=c
else if T.a[c].key>k then r:=c-1
else l:=c+1;
end;
end;
Змінні l, r і c позначають відповідно номер лівого краю, центра і правого краю частини масиву, у якій ми шукаємо елемент із заданим ключем. Пошук припиняється або якщо елемент знайдений (index <> 0), або якщо частина масиву, у якій потрібно шукати, була вичерпана (тобто номер лівого краю перевищив номер правого). Усередині циклу знаходимо номер середини частини масиву (c), потім порівнюємо ключ цього середнього елемента із шуканим ключем. Якщо виконалася рівність, то елемент знайдений, якщо середній більше шуканого, то встановлюємо праву границю частини масиву рівною c-1, якщо більше — змінюємо ліву границю на c+1.