Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
РП_31_АСД.pdf
Скачиваний:
165
Добавлен:
23.02.2016
Размер:
2.92 Mб
Скачать

Тема 12. ЗАГАЛЬНА ХАРАКТЕРИСТИКА СПИСКОВИХ СТРУКТУР ДАНИХ

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

Визначення лінійного списку та його різновидів

Приклад. Здійснюється реєстрація автомобілів, які прибувають на автостоянку та залишають її. Потрібно зберігати і обробляти множину номерів автомобілів.

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

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

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

Над зв’язаними лінійними списками виконуються наступні дії:

Додавання нового компонента на початок списку;

Додавання нового компонента в кінець списку;

Вставка нового компонента між двома наявними компонентами списку;

Видалення компонента зі списку.

Зв’язані лінійні списки поділяються на такі різновиди:

Однозв’язний лінійний список;

Двозв’язний лінійний список;

Однозв’язний циклічний список;

Двозв’язний циклічний список;

Стек;

Черга.

Однозв’язний лінійний список – це список, в якому попередній компонент посилається на наступний.

Двозв’язний лінійний список - це список, в якому попередній компонент посилається на наступний, а наступний – на попередній.

Однозв’язний циклічний список – це однозв’язний лінійний список, в якому останній компонент посилається на перший.

Двозв’язний циклічний список – це двозв’язний лінійний список, в якому останній компонент посилається на перший, а перший компонент – на останній.

37

Стек – це однозв’язний лінійний список, в якому компоненти додаються і видаляються лише з його вершини, тобто з початку списку.

Черга – це однозв’язний лінійний список, в якому компоненти додаються в кінець списку, а видаляються з вершини, тобто з початку списку.

Графічне зображення однозв’язного лінійного списку представлене на рис.1.

Поле-покажчик

nil

Рис.1 Однозв’язний лінійний список Кожний елемент однозв’язного лінійного списку складається з кількох інформаційних

полів та покажчика на наступний елемент. Отже, компонент однозв’язного лінійного списку є записом. Інформаційні поля компонента списку можуть бути змінними будь-яких типів, а покажчик повинен бути покажчиком на запис того типу, якому належать компоненти списку. Покажчик в останньому компоненті лінійного списку має значення nil – так позначається кінець списку.

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

В найпростішому випадку компонент містить одне інформаційне поле, у якому може зберігатися, наприклад, реєстраційний номер автомобіля. Для роботи з таким списком потрібні покажчики на перший і поточний компоненти. Оголосити ці покажчики можна після оголошення типу компонента списку, як показано в наступному прикладі:

type

 

ptr=^Item;

{тип покажчика на компонент списку}

Item=record

{тип компонента}

data: string;{інформаційне поле}

next: ptr;

{покажчик на наступний компонент}

end;

 

var head, current : ptr; {покажчики на перший та останній компоненти списку}

38

Тема 13. ЗВ’ЯЗНЕ ПРЕДСТАВЛЕННЯ ДАНИХ В ПАМ'ЯТІ КОМП’ЮТЕРА

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

Оскільки елементи динамічної структури розташовуються по непередбачуваним адресами пам'яті, адреса елемента такої структури не може бути обчислена на основі адреси початкового або попереднього елемента. Для встановлення зв'язку між елементами динамічної структури використовуються покажчики, через які встановлюються явні зв'язки між елементами. Таке представлення даних в пам'яті називається зв'язним. Елемент динамічної структури складається з двох полів:

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

поле зв'язок, в якому містяться один або кілька покажчиків, що зв'язує даний елемент з іншими елементами структури;

Коли зв'язне подання даних використовується для розв'язання прикладної задачі,

для кінцевого користувача "видимим" робиться тільки вміст інформаційного поля, а поле зв'язок використовується тільки програмістом-розробником.

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

розмір структури обмежується тільки доступним об'ємом машинної пам'яті;

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

Разом з тим зв’язне представлення не позбавлене й недоліків, основні з яких:

робота з покажчиками потребує, як правило, більш високої кваліфікації від програміста;

на поля зв'язок споживається додаткова пам'ять;

доступ до елементів зв'язної структури може бути менш ефективним за часом. Останній недолік є найбільш серйозним і саме їм обмежується застосовність

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

доступу (таблиці, списки, дерева тощо).

Зв'язні лінійні списки

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

39

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

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

не вказує ні на який елемент. Таке посилання позначається спеціальн им ім'ям - nil.

Машинне представл ення зв'язних лінійних списків

На рис.1 наведена структура однозв’язного списку. На ньому поле INF - інформаційне поле (дані), NE XT - покажчик на наступний елемент с писку. Кожен список повинен мати особливий е лемент, званий покажчиком початку списку або головою списку, який зазвичай за форматом відмінний від інших елементів. В поле покажчика останнього елемента списку знаходиться спеціальний ознака nil, що свідчить про кінець списку.

Рис.1. Структура однозв’язного списку Однак, обробка однозв’язного списку не завжди зручна, тому що відсутня

можливість просування в протилежну сторону. Таку можливість забезпечує двохзв'язний список, кожен елемент якого містить два покажчика: на наступний і попередній елементи списку. Структура лінійного двохзв'язной списку наведено на рис.2, де поле NEXT - покажчик на наступний елеме нт, поле PREV - покажчик на попередні й елемент. У крайніх елементах відповідні покажчи ки повинні містити nil, як і показано на рис.2.

Для зручності обробки списку додають ще один особливий елемент - покажчик кінця списку. Наявність дв ох покажчиків в кожному елементі ускладнює список і призводить до додаткових витрат пам'яті, але в той же час забезпечує більш ефективне виконання деяких операцій на д списком.

Рис.2. Структура двохзв'язного списку Різновидом розглянути х видів лінійних списків є кільцевої список, який може бути

організований на основі як однозв’язного, так і двохзв'язной сп исків. При цьому в однозв’язного списку покаж чик останнього елемента повинен вк азувати на перший елемент; в двохзв'язному списку в першому і останньому ел ементах відповідні покажчики перевизначаються, як показано на рис.3.

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

40

Рис.3. Структура кільцевого двохзв'язного списку У пам'яті список представляє собою сукупність дескриптора і однакових за

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

41