Структура даних “Список”

Дізнайтесь, що таке структура даних "Список", і як вона працює!

pic

Чому нам потрібен список?

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

Список — це лінійна колекція елементів даних, відома як вузли (nodes), що містять дані та вказівник (pointer) на наступний вузол. Порядок елементів не визначається їх фізичним розташуванням у пам'яті, натомість кожен елемент вказує на наступний елемент за допомогою вказівника (pointer). Головний/перший вузол — це вказівник, який вказує на перший вузол або головний (head) вузол у списку. Вказівник останнього вузла завжди має значення NULL або ZERO, що вказує на те, що цей вузол не з'єднаний з наступним вузлом (NODE). Список створюється в області пам'яті Heap, тому ми отримуємо динамічне виділення пам'яті.

pic

Як виглядає список!

Вузол (Node)

Розглядайте вузол як коробку, ми маємо кілька таких коробок, які з'єднані між собою і формують список. Щоб визначити вузол, потрібно вказати два компоненти: дані (data) та вказівник (pointer) на наступний вузол. Дані можуть бути будь-якого типу, що необхідно для збереження інформації, а вказівник використовується для з'єднання вузлів. Вузол міститиме вказівник типу Node, ілюстрація нижче допоможе вам зрозуміти та уявити, як виглядає вузол (Node) в списку.

pic

Вузол (Node) списку

struct Node  
{   
 int data; // частина даних вузла, може бути будь-якого типу  
 Node *next; // частина вказівника вузла, вказує на наступний вузол або NULL  
}

Як створити вузол?

Щоб створити вузол, нам потрібен вказівник (pointer), щоб він вказував на перший вузол списку в області пам'яті Heap. Як видно на малюнку нижче, ми оголосили вказівник типу Node, який вказує на перший вузол (Node). Вузол ініціалізований з даними 10, наразі частина вказівника (next) цього вузла не вказує на інший вузол, оскільки вона є NULL. Це означає, що немає наступного вузла.

pic

int main()  
{  
 Node *p;  
 p = new Node;  
 p-> data = 10;  
 p-> next = 0;  
}

Декілька важливих концепцій!

Тут у нас є два вказівники p та q, у першому рядку коду ми присвоїли p значення q, що означає, що тепер q також вказує на той самий вузол, на який вказує вказівник p.

У другому рядку q присвоюється next вказівника p (q = p-> next), це означає, що тепер вказівник q вказує на вузол, який є наступним після вказівника p.

У третьому рядку p тепер присвоюється next самого себе (p = p-> next), вказівник p вказує на наступний вузол, використовуючи адресу цього вузла.

pic

Логіка вказівників (pointers)

Реалізація списку за допомогою масиву

#include   
using namespace std;   

struct Node {  
 int data;  
 Node* next;  
};  

 Node *first = NULL;  

// функція для створення списку  
void create(int A[], int n) {  
 int i;  
 Node *t, *last;  

 first = new Node;  
 first->data = A[0];  
 first->next = NULL;  
 last = first;  

 for (i = 1; i < n; i++) {  
 t = new Node;  
 t->data = A[i];  
 t->next = NULL;  
 last->next = t;  
 last = t;  
 }  
}  

// функція для відображення списку  
void Display(Node* p) {  
 while (p != NULL) {  
 cout << p->data << " ";   
 p = p->next;  
 }  
}  

int main() {  
 int A[] = {3, 5, 7, 10, 15};  

 create(A, 5);  
 Display(first);  

 return 0;  
}

Існують й інші типи списків, які будуть розглянуті в наступних блогах!

Щасливого навчання!

Перекладено з: Linked List Data Structure

Leave a Reply

Your email address will not be published. Required fields are marked *