Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab-5.doc
Скачиваний:
7
Добавлен:
16.11.2018
Размер:
411.14 Кб
Скачать

15

Міністерство освіти І науки України

національний університет “Львівська політехніка”

Кафедра ЕОМ

Структура даних СПИСОК

Методичні вказівки

До лабораторної роботи № 5 з дисципліни

" Програмування. Частина III.

Структури даних та алгоритми "

для студентів напряму

6.050102 “Комп’ютерна інженерія”

Затверджено

на засідання кафедри

Електронні обчислювальні машини”.

Протокол № __ від ________ 2010 р. р.

Львів – 2010

Методичні вказівки до лабораторної роботи "Структура даних СПИСОК" з дисципліни “Програмування. Частина IIІ. Структури даних та алгоритми" для підготовки студентів напрямку 6.0915 “Комп’ютерна інженерія” / Укл. Т.А.Лисак – Львів: Видавництво НУ “Львівська політехніка”, 2010 – 16.

Укладач: Лисак Т.А., ст. викладач каф.ЕОМ

Відповідальний

за випуск: Мельник А.О., д-р техн. наук, проф.

Рецензенти: Мороз І.В., ст. викладач каф.ЕОМ

Юрчак І.Ю., доцент кафедри САПР, к.т.н.

1. Мета роботи

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

2. Теоретичні відомості

Лінійний список – це скінчена послідовність однотипних елементів (вузлів), можливо, з повтореннями. Список розташовується в пам'яті довільним чином. Кожний вузол однонаправленого лінійного зв'язаного списку містить вказівник на наступний вузол списку, що дозволяє переміщуватись вперед по списку. Кожний вузол двонаправленого лінійного зв'язаного списку містить вказівники на попередній і наступний вузли списку, що дозволяє переміщуватись по списку вперед та назад.

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

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

Список використовує тільки такий об'єм пам'яті, який потрібний для наявної кількості елементів.

Приклад 1: Динаміка вмісту списку

Порожній список

Реалізація списку на базі масиву

Схематичне зображення списків

0

0

Space[7]

List

0

Free

1

0

7

Space[6]

0

6

Space[5]

0

5

Space[4]

0

4

Space[3]

0

3

Space[2]

0

2

Space[1]

0

0

Space[0]

. data next

List

.

NULL

Free

0

0

0

0

0

0

0

NULL

data next

Виконаємо наступні операціїї над списком:

// push(elem) – додає elem в кінець списку

// pop(pos)- вилучає елемент, що знаходиться в позиції pos

push(106);

push (245);

push (317);

push (472);

pop (4);

push (808);

pop (3);

Результат виконання операцій

Реалізація списку на базі масиву

Схематичне зображення списків

List

1

Free

6

0

4

Space[7]

0

7

Space[6]

808

0

Space[5]

472

3

Space[4]

317

0

Space[3]

245

5

Space[2]

106

2

Space[1]

0

0

Space[0]

. data next

List

106

245

808

NULL

data next

Free

0

0

472

317

NULL

data next

Виконаємо операцію insert (pos , elem), яка вставляє elem в позицію pos:

insert (5 , 613 )

Було

Стало

List

1

Free

6

0

4

Space[7]

0

7

Space[6]

808

0

Space[5]

472

3

Space[4]

317

0

Space[3]

245

5

Space[2]

106

2

Space[1]

0

0

Space[0]

. data next

List

1

Free

7

0

4

Space[7]

613

5

Space[6]

808

0

Space[5]

472

3

Space[4]

317

0

Space[3]

245

6

Space[2]

106

2

Space[1]

0

0

Space[0]

. data next

List

106

245

808

NULL

data next

Free

0

0

472

317

NULL

data next

List

106

245

613

808

NULL

data next

Free

0

472

317

NULL

data next

Виконаємо операцію pop (pos), яка вилучає елемент, що знаходиться в позиції pos

pop (List )

Було

Стало

List

1

Free

7

0

4

Space[7]

613

5

Space[6]

808

0

Space[5]

472

3

Space[4]

317

0

Space[3]

245

6

Space[2]

106

2

Space[1]

0

0

Space[0]

. data next

List

2

Free

7

0

4

Space[7]

613

5

Space[6]

808

0

Space[5]

472

3

Space[4]

317

1

Space[3]

245

6

Space[2]

106

0

Space[1]

0

0

Space[0]

. data next

List

106

245

613

808

NULL

data next

Free

0

472

317

NULL

data next

List

245

613

808

NULL

data next

Free

0

472

317

106

NULL

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 PutAfter(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 ()

Вилучає всі елементи списку (контейнер залишається порожнім)

Приклад використання класу list з бібліотеки стандартних шаблонів STL:

// В цій програмі створюється список символів. Спочатку створюється порожній список.

// Після цього в нього поміщаються десять символів (буквы от А до J включно).

// Ця операція виконується за допомогою функції push_back(), яка додає кожне наступне значення

// в кінець створенного списку.

// Далі на екран виводиться розмір списку.

// Після цього організується вивід на екран вмісту списку

#include <iostream>

#include <list>

using namespace std;

int main()

{

list<char> lst;

int i;

for(i=0; i<10; i++) lst.push_back(’A’ + i);

cout << "Рoзмiр = " << lst.size () << endl;

list<char>::iterator p = lst.begin();

cout << "Вміст: ";

while (p != lst.end() ) {

cout << *p;

p++;

}

return 0;

}

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