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

13.3. Програмування динамічних структур даних

Найпростіші характерні прийоми обробки динамічних структур даних розглянемо на наступному прикладі:

Приклад 13.4.

а) Побудувати динамічну структуру даних, що зображена на рисунку 13.11:

F irst

Рис. 13.11.

(Дано хі - цілі числа.)

б) Прочитати дані в наступній послідовності x1 x4 x3 x1, x1 x2 x3.

Розв’язок.

Тип елемента структури визначимо наступним чином:

Type

Point = ^ Item;

Item = record

Data: Integer;

Right, Left: Point

End;

Для побудови структури використовуємо дві змінні типу Point - p і First.

Program Structure;

Type

Point = ^ Item;

Item = Record

Data: Integer;

Right, Left: Point

End;

Var

First: Point;

Procedure Build( Var First: Point);

Var p: Point;

Begin

New(p);

First := p;

Read(p^.Data); {побудований перший елемент структури}

New(p^.Left);

Read(p^.Left^.Data); {побудований другий елемент структури}

New(p^.Right);

Read(p^.Right^.Data); {побудований четвертий елемент структури}

p := p^.Left;

New(p^.Left);

p := p^.Left; Read(p^.Data);

p^.Right := Nil;

p^.left := First; {побудований третій елемент структури}

p := First^.Right; {p установлений на 4-ий елемент }

p^.Left := First^.Left;

p^.Right := First^.Left^.Left; {покажчики виставлені. Побудова закінчена}

End;

Procedure ReadGraph(First: Point);

Var p: Point;

Begin

{початок блока читання}

Writeln('x1,x4,x3,x1:');

p := First;

Write(p^.Data,'');

p := p^.Right;

Write(p^.Data,'');

p := p^.Right;

Write(p^.Data,'');

p := p^.Left;

Write(p^.Data,'');

p := First;

Writeln; Writeln('x1,x2,x3:');

Write(p^.Data,'');

p := p^.Left;

Write(p^.Data,'');

p := p^.Left;

Write(p^.Data,'');

Writeln('Кінець роботи')

End;

Begin

Build(First);

ReadGraph(First);

end.

Посилання p використовувалось для обходів структури, а First – як покажчик на початковий елемент структури.

13.4. Стеки, списки, черги

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

Type

Point = ^ Item;

Item = Record

Data: Integer;

Next: Point

End;

Відмітимо характерну деталь: описання елемента динамічної структури рекурсивне! Таким чином, описання динамічних структур неможливе без явного описання типів елементів цих структур.

місце вставки елемент, що вилучається

First

Nil

Found

Рис 13.12. Вставка та вилучення елементу зі списку.

а) Пошук. Процедура Search здійснює пошук елемента списку з числом x у якості значення поля Data і повертає посилання Found на цей елемент. Якщо такий елемент у списку відсутній, Found = Nil.

Procedure Search(var Found, First: Point; x: Integer);

Begin

Found := First;

While (Found <> Nil) and (Found^.Data <> x)

do Found := Found^.Next

End;

б) Вставка. Процедура InsList добавляє елемент у список на місце, що передує Found^ (рис. 13.13). Посилання Found встановлюється на доданий елемент.

Procedure InsList(var Found: Point, x:Integer);

Var

p: Point;

Begin

New(p);

p^.Data := Found^.data;

Found^.Data := x;

p^.Next := Found^.Next;

Found^.Next := p

End;

F ound

First

Р

Рис 13.13. Вставка елементу у список.

в) Вилучення. Процедура DelList вилучає з списку елемент Found^. Посилання Found встановлюється на елемент, що йде за вилученим.

Procedure DelList(Found: Point);

Var

p: Point;

y: Integer;

Begin

y := Found^.Next^.Data;

p:= Found^.Next;

Found^.Next := Found^.Next^.Next;

Found^.Data := y;

Dispose(p) {збирання сміття}

End;

F ound

First

P

Рис 13.14. Вилучення елементу зі списку.

Відмітимо один явний недолік процедур InsList і DelList: вони непридатні для обробки останнього елемента списку! InsList для правильної роботи потребує наявності елемента Found^.Next^, а DelList – елемента Found^.Next^.Next. Тому, якщо треба вставити в список останній елемент, покажчик Found повинен бути виставлений на Nil, але тоді Found^.Next не визначений! Аналогічна ситуація має місце і при вилученні останнього елемента.

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

а) Останній елемент списку можна вважати ознакою кінця, поле Data якого не містить значущої інформації і покажчик Found на нього за умовою не може бути встановлений.

б) Можна змінити умови вставки-вилучення: посилання Found за умовою встановлюється на елемент, що передує місцю вставки або елементу, що вилучається. Тоді окремо (поза процедур) треба розглядати випадок, коли оброблюється 1-ий елемент. Самі ж процедури в цьому варіанті спрощуються.

Procedure Ins(var Found: Point, x:Integer);

Var

p: Point;

Begin

New(p);

p^.Data := x;

p^.Next := Found^.Next;

Found^.Next := p;

End;

Procedure Del(Found: Point);

Var

p: Point;

Begin

p:= Found^.Next;

Found^.Next = Found^.Next^.Next;

Dispose(p) {збирання сміття}

End;

Часто вставці/вилученню передує пошук місця зміни списку. Для правильної роботи процедур Ins і Del процедуру Search необхідно модифікувати. Переглядати список треба "на крок уперед". Розглянемо варіант процедури пошуку місця елемента з значенням поля Data = x у списку First із упорядкованими за зростаючими значеннями полів Data.

Procedure ForwardSearch(var Found, First: Point;

var isFirst: Boolean; x: Integer);

Begin

Found := First;

If First^.Data >= x

then isFirst := True

else begin

isFirst := False:

While (Found^.Next <> Nil) and (Found^.Next^.Data < x)

do Found := Found^.Next;

end

End;

Якщо isFirst = True, то місце – перше, інакше на місце вказує Found^.Next.