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

Контрольні запитання

  1. Що відрізняє статичний масив вказівників на запис від динамічного масиву записів?

  2. Які оголошення потрібні для створення статичного масиву вказівників на запис?

  3. Як звертатись до полів динамічних записів, на які вказують елементи статичного масиву?

  4. Як виконати звільнення памяті, виділеної для таких динамічних записів?

Лабораторна робота № 5

(6 год).

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

Мета роботи: набути практичні навички створення та збереження лінійних списків. Обробка лінійних списків.

Постановка задачі: Створити найпростіше меню для виклику процедур:

  • створення списку;

  • виведення всього списку;

  • виклику заданої процедури.

Створити список заданої структури. Заповнити його інформаційну частину випадковими числами. Створити процедури для обробки списку відповідно до завдання.

Методичні вказівки до роботи:

  1. При створенні списку врахувати задану кількість елементів і їх структуру.

  2. Забезпечити заповнення списку випадковими числами відповідно до завдання.

  3. Процедурам в якості параметру передавати інформацію відповідно до типу списку та призначення процедури (адреса початку списку та ін.)

  4. Завдання відповідно до варіанту вибрати з Таблиці 5.

Зміст звіту:

    1. Задача для конкретного варіанту.

    2. Лістинг програми.

    3. Результати виконання.

    4. Висновок до роботи.

Теоретичні відомості

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

Можливість виділення та вивільнення пам’яті дозволяє створювати структури даних зі змінною кількістю елементів - динамічні структури. Найчастіше використовують зв’язані структури, коли між елементами встановлюється певна ієрархія. Серед таких структур найбільш поширеними є лінійні структури, або так звані списки і структури-дерева. В зв’язаних структурах використовуються однотипні елементи, кожен з яких має 2 різні частини:

  1. інформаційна частина - частина, що має в собі всю інформацію про об’єкт, наприклад, значення конкретного числа;

  2. посилання на сусідній елемент або елементи в конкретній ієрархії елементів.

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

Цей тип-запис має в собі тип-вказівник на елемент структури, який в свою чергу не можна визначити, поки не визначений тип елемента.

В мові PASCAL зроблено виключення з правил саме у відношенні до двох типів даних, один з яких є типом-вказівником на об’єкт другого типу. Такий запис зветься рекурсивним:

TYPE PP=^ELEM;

ELEM=RECORD

INFO:STRING[80];

POINT:PP

END;

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

  • додавання елемента структури;

  • вилучення елемента структури;

  • впорядкування структури за заданим критерієм в заданому напрямку;

  • пошук елемента структури за заданою ознакою.

В різних структурах ці операції виконуються по-різному.

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

Стек – це спеціальний тип списку, в якому усі вставки і видалення виконуються тільки з одного кінця, який зветься вершиною. Стеки також іноді звуться магазинами. Для визначення стеку в літературі застосовується така абревіатура LIFO (останній увійшов - перший вийшов). Моделлю стеку може бути колода карт, з якої можна взяти карту тільки зверху і покласти нову тільки наверх.

Інший спеціальний тип списку – черга. В ній елементи додаються з кінця черги, а видаляються – з її початку. В такому випадку зберігають два вказівними – на початок черги і на її кінець. Для визначення черги в літературі застосовується така абревіатура FIFO (перший увійшов - перший вийшов).

Спосіб індексного зберігання інформації полягає в тому, що початковий список B=<k1,k2,…,kn> ділиться на кілька підсписків B1, B2,…,Bm так, що кожний елемент списку B потрапляє до одного з підсписків. Додатково використовується індексний список з m елементів, що показують на початки списків B1, B2,…,Bm. Таке зберігання списків зветься індексним з підсписками B1, B2,…,Bm та індексним списком X=<Ag1,Ag2,…,Agm>, де Agj адреса початку підсписку Bj, . При індексному зберіганні елемент k, що належить підсписку Bi має індекс i. Для поділу списку використовується індексна функція g(k), яка виробляє за елементом k його індекс, тобто g(k)=j. Звичайно вона залежить від позиції k в B, але може залежати від значення певного його компонента - ключа.

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

USES CRT;

TYPE PP=^EL;

EL=RECORD

POLE1:INTEGER;

POLE2:BYTE;

PNT:PP;

END;

VAR PB:PP;

K,I:BYTE;

PROCEDURE VYV(UK:PP);

BEGIN

IF UK=NIL THEN WRITELN('SPYSOK POROZNIY')

ELSE WRITELN(' POLE 1','':4,'POLE 2');

WHILE UK<>NIL DO

BEGIN

WRITELN(UK^.POLE1:8,UK^.POLE2:8);

UK:=UK^.PNT;

END;

READKEY;

END;

PROCEDURE ANALIZ(UK:PP);

BEGIN

IF UK=NIL THEN WRITELN('SPYSOK POROZNIY')

ELSE

BEGIN

VYV(UK);

WRITELN;

WRITELN('POLE1 ZAPYSIV Z PARNYM POLE2:');

WHILE UK<>NIL DO

BEGIN

IF UK^.POLE2 MOD 2 =0 THEN WRITELN(UK^.POLE1:6);

UK:=UK^.PNT;

END; END;

READKEY;

END;

PROCEDURE STVOR(VAR UK:PP);

VAR TT:PP;

BEGIN

RANDOMIZE;

NEW(TT);

UK:=TT;

TT^.POLE1:=RANDOM(50)-25;

TT^.POLE2:=RANDOM(100);

FOR I:=1 TO 10 DO

BEGIN

NEW(TT^.PNT);

TT:=TT^.PNT;

TT^.POLE1:=RANDOM(50)-25;

TT^.POLE2:=RANDOM(100);

END;

TT^.PNT:=NIL;

WRITELN('SPYSOK STVORENO');

READKEY;

END;

BEGIN

WHILE TRUE DO

BEGIN

CLRSCR;

WRITELN('MENU:');

WRITELN('1:STVORITY SPISOK');

WRITELN('2:VYVESTY SPISOK');

WRITELN('3:ANALYZ SPISKU');

WRITELN('4:VYHID Z PROGRAMY');

WRITE('VYBRATY PUNKT MENU:');

READ(K);

CASE K OF

1:STVOR(PB);

2:VYV(PB);

3:ANALIZ(PB);

4:HALT;

ELSE

BEGIN

WRITELN('POMILKA'); READKEY; CONTINUE

END;

END;

END;

END.

Приклад: Створити однонаправлений лінійний список з 10 елементів. Інформаційна частина елементів списку має одне поле типу byte, дані є випадковими числами. Вивести вміст створеного списку. Інформацію списку обробити таким чином: парні елементи вивести на екран, а непарні в типізований файл. Звільнити пам’ять, зайняту списком. Далі вивести інформацію з файлу. Створити процедури обслуговування.

USES CRT;

TYPE UK=^EL;

EL=RECORD

DIG:BYTE;

AD:UK

END;

FTYPE=FILE OF BYTE;

VAR PB,PE,PT:UK;

F:FTYPE;

I:BYTE;

PROCEDURE WRLIST(PP:UK);

BEGIN

WRITELN('ВИВЕДЕННЯ ЕЛЕМЕНТІВ СПИСКУ');

WHILE PP<>NIL DO

BEGIN

WRITE(PP^.DIG:4);

PP:=PP^.AD;

END;

END;

PROCEDURE WRFL(VAR FF:FTYPE);

VAR ZM:BYTE;

BEGIN

WRITELN('ВИВЕДЕННЯ ЕЛЕМЕНТІВ ФАЙЛУ');

RESET(FF);

WHILE NOT EOF(FF) DO

BEGIN

READ(FF,ZM);

WRITE(ZM:4);

END;

CLOSE(FF);

END;

PROCEDURE DISPLIST(VAR PP:UK);

VAR TMP:UK;

BEGIN

TMP:=PP;

WHILE PP<>NIL DO

BEGIN

PP:=PP^.AD;

DISPOSE(TMP);

TMP:=PP;

END;

PP:=NIL;

WRITELN(‘ПАМ’’ЯТЬ ЗВІЛЬНЕНА ');

END;

BEGIN

RANDOMIZE;

CLRSCR;

NEW(PT);

PB:=PT;

PT^.DIG:=RANDOM(25);

FOR I:=1 TO 9 DO

BEGIN

NEW(PT^.AD);

PT^.AD^.DIG:=RANDOM(25);

PT:=PT^.AD;

END;

PT^.AD:=NIL;

PE:=PT;

PT:=PB;

WRLIST(PB);

ASSIGN(F,'TXT');

REWRITE(F);

PT:=PB;

WRITELN;

WRITELN('ВИВЕДЕННЯ ПАРНИХ ЕЛЕМЕНТІВ НА ЕКРАН, А НЕПАРНИХ - В ФАЙЛ');

WHILE(PT<>NIL) DO

BEGIN

IF ODD(PT^.DIG) THEN WRITE(F,PT^.DIG) ELSE WRITE(PT^.DIG:4);

PT:=PT^.AD;

END;

CLOSE(F);

WRITELN;

WRFL(F);

WRITELN;

DISPLIST(PB);

WRLIST(PB);

READKEY

END.

Результати виконання програми:

виведення елементів списку

22 9 24 7 17 12 17 6 20 16

виведення парних елементів на екран, а непарних - в файл

22 24 12 6 20 16

виведення елементів файлу

9 7 17 17

пам’ять звільнена 

виведення елементів списку