Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Posibnyk_C.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.61 Mб
Скачать

11 Динамічні конструкції даних

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

11.1 – Зв’язані списки

Зв’язаний список – одна з найважливіших структур даних, у якій елементи лінійно впорядковані, але порядок визначається не номерами елементів, як у масивах, а вказівниками, що входять до складу елементів списку. Список має “голову” – перший та “хвіст” – останній елемент. Зв’язаний список – не новий тип, а спосіб організації даних відомих типів. Для побудови зв’язаного списку найкраще підходять структури, тоді кожна з них є одним елементом списку, крім власне даних, вони містять один або більше вказівників для запам’ятовування адрес сусідніх структур. Ці вказівники мусять мати тип тієї структури, на яку вони вказують. Нагадаємо, що вказівник – це змінна, призначена для запам’ятовування адреси, а його тип визначає крок розміщення даних у пам’яті. Таким чином, одержуємо ніби ланцюжок певної кількості структур, зв’язаних між собою за допомогою адрес.

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

Однобічно зв’язаний список є найпростішим, кожний його елемент (структура) містить один вказівник, який запам’ятовує адресу, назвемо її dali, наступного елемента. Якщо вказівник не вказує на інший елемент, тобто dali = NULL, то вважається, що даний елемент є останнім у списку. Крім вказівника dali, програма має мати ще й вказівник на перший елемент списку, назвемо його head, який служить для заходу в список. Якщо список порожній, то цьому вказівнику теж присвоюють значення NULL. Однобічно зв’язаний список забезпечує послідовний доступ до своїх елементів у одну сторону – від початку до кінця. Під час гортання списку (наприклад, під час пошуку потрібного елемента) ні вказівник head, ні кожний із вказівників dali не змінюють своїх значень (адрес), тому для запам’ятовування адреси поточного елемента теж використовується вказівник, назвемо його curr. Гортання списку відбувається в циклі, умовою завершення якого є curr == NULL.

Двобічно зв’язаний список подібно до вищерозгляненого однобічно зв’язаного теж забезпечує послідовний доступ до своїх елементів, але, на відміну від нього, дозволяє гортати список як від початку до кінця, так і навпаки. Кожний його елемент містить два вказівники: один dali, який вказує на наступний елемент, а другий, назвемо його prev, який вказує на попередній. Якщо prev=NULL, то в елемента немає попередника, тобто він є “головою” списку, якщо dali=NULL, то в нього немає наступника – “хвіст” списку.

Кільцевий список може бути як однобічно, так і двобічно зв’язаним. У ньому зв’язується перший елемент з останнім. Тобто, в однобічно зв’язаному списку вказівник dali “хвоста” дорівнює head. У двобічно зв’язаному вказівник prev “голови” вказує на “хвіст”, а вказівник dali “хвоста” – на “голову” списку.

Застосування списків. Зв’язані списки інтенсивно застосовуються в програмуванні як самостійні структури. Вони мають деякі переваги над масивами. Вони більш ефективні при додаванні або вилученні елемента в довільному місці списку, бо виконують ці операції за постійний час, тоді як у масивах час зростає з ростом кількості елементів. В списках не існує проблеми “розширення”, яка рано чи пізно виникає в масивах фіксованого розміру, коли виникає необхідність включити в нього додаткові елементи. На відміну від масивів вони не потребують неперервної області пам’яті. Також масив фіксованого розміру, з якого було вилучено багато елементів (або вони просто не використовуються) є дуже неефективним з погляду на використання пам’яті.

Таблиця 11.1 – Приклад масиву структур

Код

підприємства

Назва

підприємства

Статутний фонд,

млн у. о.

1

Харкiвтрансгаз

34,60

2

Прикарпаттрансгаз

22,15

3

Київтрансгаз

75,00

4

Львiвтрансгаз

42,12

5

Експорттрансгаз

1,85

6

Гадячгазпром

12,48

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

Утворення і звертання до елементів (вивід на екран) та редагування зв’язаного списку показано в програмі прикладу 11.1.

Приклад 11.1 – Створення та редагування зв’язаного списку

#include<stdio.h>

#include<stdlib.h> /* Для функції malloc() */

#include<string.h> /* Для функції strcpy() */

struct pidpr{int kod;

char naz[32];

float stf;

struct pidpr *dali;};

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]