
- •До лабораторної роботи № 5 з дисципліни
- •6.050102 “Комп’ютерна інженерія”
- •1. Мета роботи
- •2. Теоретичні відомості
- •3. Порядок виконання роботи
- •4. Завдання на лабораторну роботу
- •4.1. Вибір варіанта індивідуального завдання
- •4.2. Варіанти завдань
- •5. Вимоги до оформлення звіту
- •1. Мета роботи
- •6. Контрольні завдання
- •Список літератури
- •Мета роботи……………………………………..……………………………………………3
- •Теоретичні відомості..........….………………………………………………………….…. .3
- •Методичні вказівки
- •"Структура даних список"
- •6.050102 “Комп’ютерна інженерія”
Міністерство освіти І науки України
національний університет “Львівська політехніка”
Кафедра ЕОМ
Структура даних СПИСОК
Методичні вказівки
До лабораторної роботи № 5 з дисципліни
" Програмування. Частина III.
Структури даних та алгоритми "
для студентів напряму
6.050102 “Комп’ютерна інженерія”
Затверджено
на засідання кафедри
“Електронні обчислювальні машини”.
Протокол № __ від ________ 2012
р. р.
Львів – 2012
Методичні вказівки до лабораторної роботи "Структура даних СПИСОК" з дисципліни “Програмування. Частина IIІ. Структури даних та алгоритми" для підготовки студентів напрямку 6.0915 “Комп’ютерна інженерія” / Укл. Т.А.Матвейчук – Львів: Видавництво НУ “Львівська політехніка”, 2012 – 16.
Укладач: Матвейчук Т.А., ст. викладач каф.ЕОМ
Відповідальний
за випуск: Мельник А.О., д-р техн. наук, проф.
Рецензенти: Мороз І.В., ст. викладач каф.ЕОМ
Юрчак І.Ю., доцент кафедри САПР, к.т.н.
1. Мета роботи
Вивчення фундаментальної абстрактної структури даних списка. Набуття практичних навичок побудови списка, дослідження динаміки його вмісту та використання списків для розв'язання прикладних задач.
2. Теоретичні відомості
Лінійний список – це скінчена послідовність однотипних елементів (вузлів), можливо, з повтореннями. Список розташовується в пам'яті довільним чином. Кожний вузол однонаправленого лінійного зв'язаного списку містить вказівник на наступний вузол списку, що дозволяє переміщуватись вперед по списку. Кожний вузол двонаправленого лінійного зв'язаного списку містить вказівники на попередній і наступний вузли списку, що дозволяє переміщуватись по списку вперед та назад.
Вставка і вилучення вузлів у списку реалізовані ефективно: змінюються тільки вказівники. З іншого боку, довільний доступ до вузлів списку підтримується погано: щоб прийти до певного вузла списку, треба відвідати всі попередні вузли. Крім того, на відміну від стеків або черг, додатково витрачається пам'ять під один або два вказівники на кожний елемент списку.
Список росте дуже просто: додавання кожного нового елемента приводить до того, що вказівники на попередній і наступний вузли списку, між якими вставляється новий вузол, міняють свої значення. У новому елементі таким вказівникам присвоюється значення адрес сусідніх елементів.
Список використовує тільки такий об'єм пам'яті, який потрібний для наявної кількості елементів.
Приклад 1: Динаміка вмісту списку
Порожній список |
||||||||||||||||||||||||||||||
Реалізація списку на базі масиву |
Схематичне зображення списків |
|||||||||||||||||||||||||||||
. data next
|
|
L . NULL |
||||||||||||||||||||||||||||
|
F ree
data next |
Виконаємо наступні операціїї над списком: // push(elem) – додає elem в кінець списку // pop(pos)- вилучає елемент, що знаходиться в позиції pos push(106); push (245); push (317); push (472); pop (4); push (808); pop (3);
|
Результат виконання операцій |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Реалізація списку на базі масиву |
Схематичне зображення списків |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
. data next
|
|
data next
Free
data next |
Виконаємо операцію insert (pos , elem), яка перед елементом, що знаходиться в позиції pos, вставляє новий елемент зі значенням elem:
insert (5 , 613 ) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Було |
Стало |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
. data next
|
|
. data next
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
List
data next
Free
data next |
List
data next
Free
data next |
Виконаємо операцію pop (pos), яка вилучає елемент, що знаходиться в позиції pos
pop (List ) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Було |
Стало |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
. data next
|
|
. data next
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
List
data next
Free
data next |
List
data next
Free
data next |
Розглянемо програмну реалізацію деяких основних операцій роботи з лінійним зв'язаним однонаправленим списком, представленим за допомогою вказівників:
// Структура списка
struct node
{ int data;
struct node *next;
};
typedef struct node *list;
// Додавання нового елемента в кінець списку
void push(list *head_ptr, int elem)
{
node *new_ptr;
new_ptr = new node;
new_ptr->data = elem;
new_ptr->next = NULL;
if (empty(*head_ptr))
*head_ptr = new_ptr;
else
find_last(*head_ptr)->next = new_ptr;
return ;
}
// Вставка нового елемента після заданого елемента списку
void put_after(list *node_prt, int elem)
{
list new_ptr = NULL;
new_ptr = new node;
new_ptr->data = elem;
new_ptr->next = (*node_prt)->next;
(*node_prt)->next = new_ptr;
return ;
}
// Пошук вузла із заданим значенням в списку
list find(list head, infotype search_data)
{
while ((head) && (head->data != search_data)) head = head->next;
return head;
}
// Пошук вузла в списку, що знаходиться перед заданим вузлом
list find_before(list head, list node)
{
while ((head->next != node) && head) head = head->next;
return head;
}
// Пошук вузла в списку що знаходиться після заданого вузла
list find_after(list node)
{
return node->next;
}
// Пошук останнього вузла списку
list find_last(list head)
{
if (head) while (head->next) head = head->next;
return head;
}
// Вилучення заданого вузла зі списку
void delete(list *head_ptr, list *node_ptr)
{
list tmp , save_ptr = *node_ptr;
assert(*head_ptr);
assert(*node_ptr);
if (*node_ptr == *head_ptr)
*head_ptr = (*head_ptr)->next;
else
if (!((*node_ptr)->next))
{
tmp = FindBefore(*head_ptr,*node_ptr);
tmp->next = NULL;
}
else
{
tmp = (*node_ptr)->next;
(*node_ptr)->data = tmp->data;
(*node_ptr)->next = tmp->next;
save_ptr = tmp;
};
free(save_ptr);
return ;
}
// Роздрук списку
void print_list(list head)
{
while (head)
{
cout<<head->data;
head = head->next;
}
cout<<endl;
return;
}
В бібліотеці стандартних шаблонів STL існує клас list, що підтримує двунаправлений лінійний список. В класі list визначений конструктор list, що створює порожній список. Нижче в таблиці наведені основні функції-члени класу list:
Функція-член |
Опис |
begin () |
Повертає двонаправлений ітератор для першого елемента |
end () |
Повертає двонаправлений ітератор для позиції за останнім елементом |
insert (pos , elem) |
Вставляє копію elem в позицію ітератора pos і повертає позицію нового елемента |
push_back (elem) |
Додає копію elem в кінець списку |
push_front (elem) |
Вставляє копію elem в початок списку |
pop_back (elem) |
Вилучає останній елемент списку (не повертаючи його) |
pop_front (elem) |
Вилучає перший елемент списку (не повертаючи його) |
remove (val) |
Вилучає всі елементи списку зі значенням val |
erase (pos) |
Вилучає елемент в позиції ітератора pos і повертає позицію наступного елемента списку |
clear () |
Вилучає всі елементи списку (контейнер залишається порожнім) |