Зв’язний список - студопедія
Структура даних, що представляє собою кінцеве безліч впорядкованих елементів (вузлів), пов'язаних один з одним за допомогою покажчиків, називається зв'язковим списком. Кожен елемент зв'язного списку містить поле з даними, а також покажчик (посилання) на наступний і / або попередній елемент. Ця структура дозволяє ефективно виконувати операції додавання і видалення елементів для будь-якої позиції в послідовності. Причому це не зажадає реорганізації структури, яка б була потрібна в масиві. Мінусом зв'язного списку, як і інших структур типу «список», в порівнянні його з масивом є відсутність можливості працювати з даними в режимі довільного доступу, т. Е. Список - структура послідовно доступу, в той час як масив - довільного. Останній недолік знижує ефективність ряду операцій.
Кожен вузол однозв'язного (односпрямованого зв'язкового) списку містить покажчик на наступний вузол (рис. 2.7). З однієї точки можна потрапити лише в наступну точку, рухаючись тим самим в кінець. Так виходить своєрідний потік, поточний в одному напрямку.
Малюнок 2.7 - однозв'язного список
Повторимо вже раніше сказане. На зображенні кожен з блоків представляє елемент (вузол) списку. Head list - заголовний елемент списку (для нього передбачається поле next). Він не містить дані, а тільки посилання на наступний елемент. На наявність даних вказує поле info. а посилання - поле next (далі за посилання буде відповідати і поле prev). Ознакою відсутності покажчика є поле nil.
Однозв'язний список не найзручніший тип зв'язного списку, т. К. З однієї точки можна потрапити лише в наступну точку, рухаючись тим самим в кінець. Коли крім покажчика на наступний елемент є вказівник на попередній, то такий список називається двусвязного.
Малюнок 2.8 - двусвязного список
Можливість рухатися як вперед, так і назад корисна для виконання деяких операцій, але додаткові покажчики вимагають залучення більшої кількості пам'яті, ніж такої необхідно в однозв'язного списку.
Коли кількість пам'яті, з яких-небудь причин, обмежена, тоді альтернативою двусвязного списку може послужити XOR-зв'язний список (рис. 2.9). Останній використовує логічну операцію XOR (виключає «АБО», сувора диз'юнкція), яка для двох змінних повертає істину лише за умови, що істинно тільки одне з них, а друге, відповідно, помилково. Таблиця істинності операції:
Малюнок 2.9 - XOR-зв'язний список
Ще один вид зв'язного списку - кільцевої список. У кільцевому однозв'язного списку останній елемент посилається на перший. У разі двусвязного кільцевого списку, плюс до цього, перший елемент посилається на останній (рис. 2.10). Таким чином, виходить зациклена структура.
Малюнок 2.10 - Кільцевій зв'язний список
Розглянемо основні операції над зв'язковими списками.
На прикладі двусвязного списку, розберемо принцип роботи цієї структури даних. При реалізації списку зручно використовувати структури (в Pascal - записи).
Загальна форма опису вузла двонаправленого зв'язного списку і покажчика на перший елемент списку:
інформаційне поле 1;
інформаційне поле 2;
інформаційне поле n;
покажчик на наступний елемент;
покажчик на попередній елемент;
struct DoubleList // опис вузла списку
int data; // інформаційне поле
DoubleList * next; // покажчик на наступний елемент
DoubleList * prev; // покажчик на попередній елемент
DoubleList * head; // покажчик на перший елемент списку
Тепер, припускаючи, що описаний вузол і покажчик на голову списку (див. Приклад вище), напишемо функції обробки списку.
void AddList (int value, int position)
DoubleList * node = new DoubleList; // створення нового елемента
node-> data = value; // присвоєння елементу значення
if (head == NULL) // якщо контактів немає
node-> next = node; // установка покажчика next
node-> prev = node; // установка покажчика prev
head = node; // визначається голова списку
for (int i = position; i> 1; i--) p = p-> next;
node-> next = p; // додавання елемента
cout<<"\nЭлемент добавлен. \n\n";
int DeleteList (int position)
if (head == head-> next) // якщо це останній елемент в списку
delete head; // видалення елемента
for (int i = position; i> 1; i--) a = a-> next;
if (a == head) head = a-> next;
a-> prev-> next = a-> next; // видалення елемента
cout<<"\nЭлемент удален. \n\n";
Якщо список порожній, то виводиться повідомлення, що сповіщає про це, і функція повертається в місце виклику.
Функція PrintList виводить на екран всі елементи списку:
if (head == NULL) cout<<"Список пуст\n";
cout<<"\nЭлементы списка: ";
Вивести список можна і за допомогою циклу, тобто итеративно. Тепер з'єднаємо ці три функції в одній програмі, а також напишемо головну функцію, що відповідає за виклик підпрограм:
struct DoubleList // опис вузла списку
int data; // інформаційне поле
DoubleList * next; // покажчик на наступний елемент
DoubleList * prev; // покажчик на попередній елемент
DoubleList * head; // покажчик на перший елемент списку
void AddList (int value, int position) // додавання елемента
DoubleList * node = new DoubleList; // створення нового елемента
node-> data = value; // присвоєння елементу значення
if (head == NULL) // якщо контактів немає
node-> next = node; // установка покажчика next
node-> prev = node; // установка покажчика prev
head = node; // визначається голова списку
for (int i = position; i> 1; i--) p = p-> next;
node-> next = p; // додавання елемента
cout<<"\nЭлемент добавлен. \n\n";
int DeleteList (int position) // видалення елемента
if (head == head-> next) // якщо це останній елемент в списку
delete head; // видалення елемента
for (int i = position; i> 1; i--) a = a-> next;
if (a == head) head = a-> next;
a-> prev-> next = a-> next; // видалення елемента
cout<<"\nЭлемент удален. \n\n";
void PrintList () // висновок списку
if (head == NULL) cout<<"Список пуст\n";