Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Laboratornaya_rabota_7_условие.docx
Скачиваний:
4
Добавлен:
12.07.2022
Размер:
36.99 Кб
Скачать

ЛАБОРАТОРНАЯ РАБОТА № 7

ДИНАМИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ

1. Динамические структуры данных

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

Из динамических структур в программах чаще всего используются линейные списки, стеки, очереди и бинарные деревья.

Самый простой способ связать множество элементов – сделать так, чтобы каждый элемент содержал ссылку на следующий. Такой список называется однонаправленным (односвязным). Если добавить в каждый элемент вторую ссылку – на предыдущий элемент, получится двунаправленный список (двусвязный), если последний элемент связать указателем с первым, получится кольцевой список.

Типовая структура двунаправленного линейного списка может выглядеть так:

struct Node{

int d;

Node *next;

Node *prev;

};.

Каждый элемент списка содержит ключ, идентифицирующий этот элемент. Ключ обычно бывает либо целым числом, либо строкой и является частью поля данных. В качестве ключа в процессе работы со списком могут выступать разные части поля данных. Например, если создается линейный список из записей, содержащих фамилию, год рождения, стаж работы и пол, любая часть записи может выступать в качестве ключа: при упорядочивании списка по алфавиту ключом будет фамилия, а при поиске, к примеру, ветеранов труда ключом будет стаж. Ключи разных элементов списка могут совпадать.

Над списками можно выполнять следующие операции:

– начальное формирование списка (создание первого элемента);

– добавление элемента в конец списка;

– чтение элемента с заданным ключом;

– вставка элемента в заданное место списка (до или после элемента с заданным ключом);

– удаление элемента с заданным ключом;

– упорядочивание списка по ключу.

2. Пример работы с линейным списком

Задание

Составить программу, формирующую сведения об отправлении поездов.

Каждый поезд описывается с помощью структуры, содержащей следующие поля:

– номер поезда (ключ списка);

– пункт назначения;

– время отправления.

Данные хранятся в виде двунаправленного линейного списка.

Программа должна реализовывать следующие операции:

– формирование меню для выбора действия пользователем;

– ввод данных в список, отсортированный по ключу;

– вывод данных из списка в виде таблицы;

– поиск элемента в списке по различным критериям (номеру поезда, имени пункта назначения, времени отправления);

– удаление элемента из списка по заданному ключу.

Текст программы

#include <Windows.h>

#include <iostream>

#include <iomanip>

using namespace std;

//Структура для формирования списка

struct Train {

int train_num; //Номер поезда

char p_nazn[20]; //Имя пункта назначения

char v_otpr[10]; //Время отправления

Train* prev; //Указатель на предыдущий элемент

Train* next; //Указатель на последующий элемент

};

Train* pbeg; //Указатель на начало списка

Train* pend; //Указатель на конец списка

//Список функций программы

void menu(); //Функция прорисовки меню

//Функция формирования первого элемента списка

Train* first(int t_num, char* p_nazn, char* v_otpr);

//Функция вставки элемента в упорядоченный список

void add_sort(Train** pbeg, Train** pend, int t_num, char* p_nazn, char* v_otpr);

//Функция поиска элемента по ключу (номер поезда)

Train* find(Train* const pbeg, int t_num);

//Функция поиска элемента по имени пункта назначения

bool find_punkt(Train* const pbeg, char* p_nazn);

//Функция поиска элемента по времени отправления

bool find_time(Train* const pbeg, char* v_otpr);

//Функция удаления элемента из списка по заданному

// ключу

bool remove(Train** pbeg, Train** pend, int key);

void vvod(); //Функция ввода данных в список

void vivod(); //Функция вывода элементов списка

//на экран

void search(); //Функция поиска элементов в списке

void del(); //Функция удаления элемента

// из списка

void hline(); //Функция прорисовки

//горизонтальной линии

int main()

{

SetConsoleCP(1251);

SetConsoleOutputCP(1251);

pbeg = 0; //Инициализация указателя на первый

//элемент списка

pend = 0; //Инициализация указателя на последний

//элемент списка

int num = 0; //Переменная для хранения номера

//выбранного пункта меню

//Цикл обработки действий пользователя

while (num != 5)

{

menu();

cin >> num;

switch (num) {

case 1: vvod(); break;

case 2: vivod(); break;

case 3: search(); break;

case 4: del(); break;

case 5: break;

default: cout << "Неверный вариант выбора";

}

}

return 0;

}

void menu()

{

cout << "\n МЕНЮ \n";

cout << "1. Ввод данных\n";

cout << "2. Вывод данных\n";

cout << "3. Поиск\n";

cout << "4. Удаление\n";

cout << "5. Выход\n";

cout << "\nВведите номер пункта меню для дальнейшей работы\n";

}

//Функция формирования первого элемента списка

Train* first(int t_num, char* p_nazn, char* v_otpr)

{

//Создание нового элемента

Train* pv = new Train;

//Заполнение полей данных

pv->train_num = t_num;

strcpy_s(pv->p_nazn, p_nazn);

strcpy_s(pv->v_otpr, v_otpr);

//Инициализация указателей на соседние

//элементы списка

pv->prev = 0;

pv->next = 0;

return pv;

}

void add_sort(Train** pbeg, Train** pend, int t_num, char* p_nazn, char* v_otpr)

{

//Создание нового элемента

Train* pv = new Train;

//Заполнение полей данных

pv->train_num = t_num;

strcpy_s(pv->p_nazn, p_nazn);

strcpy_s(pv->v_otpr, v_otpr);

Train* pt = *pbeg;

while (pt) { //Просмотр списка

if (t_num < pt->train_num)

{

pv->next = pt;

if (pt == *pbeg) //Вставка в начало

//списка

{

pv->prev = 0;

*pbeg = pv;

}

else //Вставка в середину

// списка

{

(pt->prev)->next = pv;

pv->prev = pt->prev;

}

pt->prev = pv;

return;

}

pt = pt->next;

}

pv->next = 0; //Вставка в конец списка

pv->prev = *pend;

(*pend)->next = pv;

*pend = pv;

}

//Функция поиска элемента по номеру поезда

Train* find(Train* const pbeg, int t_num)

{

Train* pv = pbeg;

while (pv)

{

if (pv->train_num == t_num)

break;

pv = pv->next;

}

return pv;

}

//Функция поиска элемента по имени пункта назначения

bool find_punkt(Train* const pbeg, char* p_nazn)

{

bool find = false;

Train* pv = pbeg;

while (pv) //Просмотр списка

{

if (strcmp(pv->p_nazn, p_nazn) == 0)

{

find = true;

//Вывод на экран найденного элемента

cout << setw(5) << pv->train_num << setw(20) << pv->p_nazn << setw(10) << pv->v_otpr;

}

pv = pv->next;

}

return find;

}

//Функция поиска элемента по времени отправления

bool find_time(Train* const pbeg, char* v_otpr)

{

bool find = false;

Train* pv = pbeg;

while (pv) //Просмотр списка

{

if (strcmp(pv->v_otpr, v_otpr) == 0)

{

find = true;

//Вывод на экран найденного элемента

cout << setw(5) << pv->train_num << setw(20) << pv->p_nazn << setw(10) << pv->v_otpr;

}

pv = pv->next;

}

return find;

}

//Функция удаления элемента из списка

bool remove(Train** pbeg, Train** pend, int key)

{

if (Train* pkey = find(*pbeg, key))

{

//Если удаляется первый элемент из списка

if (pkey == *pbeg)

{

*pbeg = (*pbeg)->next;

if (*pbeg) (*pbeg)->prev = 0;

}

else

//Если удаляется последний элемент из списка

if (pkey == *pend)

{

*pend = (*pend)->prev;

(*pend)->next = 0;

}

//Если удаляется элемент из середины списка

else

{

(pkey->prev)->next = pkey->next;

(pkey->next)->prev = pkey->prev;

}

delete pkey;

return true;

}

return false;

}

//Функция ввода данных

void vvod()

{

int n;

int t_num;

char p_nazn[20];

char v_otpr[10];

//Ввод количества добавляемых записей

cout << "Введите кол-во добавляемых записей в список = ";

cin >> n;

//Цикл для ввода полей структуры

for (int i = 0; i < n; i++)

{

cout << "\nВведите номер поезда\n";

cin >> t_num;

cout << "Введите имя пункта назначения\n";

while (cin.get() != '\n');

cin.getline(p_nazn, 20);

cout << "Введите время отправления\n";

cin.getline(v_otpr, 10);

//Если в списке есть элементы - добавляется новый

// элемент с сортировкой списка

if (pbeg)

add_sort(&pbeg, &pend, t_num, p_nazn, v_otpr);

//Если список пуст - формируется первый

//элемент списка

else

{

pbeg = first(t_num, p_nazn, v_otpr);

pend = pbeg;

}

}

}

//Функция вывода списка на экран в виде таблицы

void vivod()

{

if (pbeg) //Если список не пуст - вывод на экран

{

//Прорисовка шапки таблицы

cout << "\n Список поездов\n";

hline();

cout << "| Номер | Пункт назначения | Время отп. |\n";

hline();

//Вывод элементов списка на экран

Train* pv = pbeg;

while (pv)

{

cout << "| " << setw(5) << pv->train_num;

cout << " | " << setw(20) << pv->p_nazn;

cout << " | " << setw(10) << pv->v_otpr << " |" << endl;

pv = pv->next;

}

//Отчеркивание нижней гранцы таблицы

hline();

}

else //Если список пуст - вывод сообщения

cout << "\nСписок пуст!\n";

}

//Функция поиска элементов в списке

void search()

{

if (pbeg)

{

int k_poisk;

//Прорисовка меню выбора критерия поиска

cout << "\nВыберите критерий поиска\n";

cout << "1. Поиск по номеру поезда\n";

cout << "2. Поиск по имени пункта назначения\n";

cout << "3. Поиск по времени отправления\n";

cout << "\nВведите номер критерия ";

cin >> k_poisk;

//Обработка выбора критерия пользователем

switch (k_poisk)

{

case 1: //Поиск по номеру поезда

int t_num;

cout << "\nВведите номер поезда ";

cin >> t_num;

if (Train* pv = find(pbeg, t_num))

{

cout << "\nРезультат поиска:\n";

cout << setw(5) << pv->train_num << setw(20) << pv->p_nazn << setw(10) << pv->v_otpr;

}

else

cout << "Поезд с таким номером не найден\n";

break;

case 2: //Поиск по имени пункта назначения

char p_nazn[20];

cout << "\nВведите имя пункта назначения\n";

while (cin.get() != '\n');

cin.getline(p_nazn, 20);

cout << "\nРезультат поиска:\n";

if (!find_punkt(pbeg, p_nazn))

cout << "Поезда с таким пунктом назначения не найдены\n";

break;

case 3: //Поиск по времени отправления

char v_otpr[10];

cout << "\nВведите время отправления\n";

while (cin.get() != '\n');

cin.getline(v_otpr, 10);

cout << "\nРезультат поиска:\n";

if (!find_time(pbeg, v_otpr))

cout << "Поезда с таким временем отправления не найдены\n";

break;

default: cout << "Неверный вариант выбора\n";

}

}

else

cout << "\nСписок пуст!\n";

}

//Функция удаления элемента из списка

void del()

{

if (pbeg)

{

int t_num;

//Ввод номера поезда для поиска и удаления

//соответствующей записи

cout << "Введите номер поезда ";

cin >> t_num;

if (remove(&pbeg, &pend, t_num))

cout << "\nЗапись удалена\n";

else

cout << "\nЗапись с таким номером не найдена\n";

}

else

cout << "\nСписок пуст!\n";

}

//Функция для проведения горизонтальной линии

// в таблице

void hline()

{

const int m = 45;

for (int i = 0; i < m; i++)

cout << "-";

cout << endl;

}

3. Варианты работы

Создать программу, формирующую данные определенной структуры в виде двунаправленного линейного списка. Структура данных зависит от варианта.

Программа должна реализовывать следующие операции:

– формирование меню для выбора действия пользователем;

– ввод данных в список, отсортированный по ключу;

– вывод данных из списка в виде таблицы;

– поиск элемента в списке по различным критериям (номеру поезда, имени пункта назначения, времени отправления);

– удаление элемента из списка по заданному ключу.

1. Составить программу, которая обрабатывает информацию о наличии автобусов в автобусном парке.

Сведения о каждом автобусе содержат:

– номер автобуса (ключ);

– ФИО водителя;

– номер маршрута.

2. Составить программу, которая обрабатывает информацию о книгах в библиотеке.

Сведения о книгах содержат:

– номер УДК (ключ);

– ФИО автора;

– название;

– год издания.

3. Составить программу, которая обрабатывает информацию о заявках на авиабилеты.

Каждая заявка содержит:

– номер рейса (ключ);

– пункт назначения;

– ФИО пассажира;

– желаемую дату вылета.

4. Составить программу, формирующую телефонный справочник.

Сведения об абоненте содержат:

– номер телефона (ключ);

– ФИО абонента;

– адрес абонента.

5. Составить программу, которая обрабатывает информацию о наличии бензина на автозаправочной станции.

Сведения о бензине содержат:

– марка бензина (ключ);

– цена за литр;

– количество литров наличии.

6. Составить программу, которая обрабатывает информацию о врачах, работающих в поликлинике.

Сведения о враче содержат:

– табельный номер врача (ключ);

– ФИО врача;

– специализация;

– номер кабинета.

7. Составить программу, которая обрабатывает информацию о гражданах, лежащих в больнице.

Сведения о больном содержат:

– номер больного (ключ)

– ФИО больного;

– диагноз;

– номер палаты.

8. Составить программу, которая обрабатывает информацию для учета автомобильных грузоперевозок.

Сведения о грузовике содержат:

– номер грузовика (ключ);

– ФИО водителя;

– грузоподъемность.

9. Составить программу, которая обрабатывает информацию о наличии приборов на складе.

Сведения о приборе содержат:

– название прибора (ключ);

– тип прибора;

– цена;

– количество на складе.

10. Составить программу, которая обрабатывает информацию о заказах на ремонт вычислительной техники.

Сведения о заказе содержат:

– номер заказа (ключ);

– ФИО заказчика;

– описание неисправности;

– стоимость ремонта.

11. Составить программу, которая обрабатывает информацию о лабораториях института.

Сведения о лаборатории содержат:

– номер лаборатории (ключ);

– количество компьютеров;

– ФИО ответственного лаборанта.

12. Составить программу, которая обрабатывает информацию о мебельных гарнитурах, продаваемых в магазине.

Сведения о гарнитуре содержат:

– название гарнитура (ключ);

– количество предметов;

– цена;

– наличие на складе.

13. Составить программу, которая обрабатывает информацию о продаже автомобилей в автосалоне.

Сведения об автомобиле содержат:

– номер автомобиля (ключ);

– марка автомобиля;

– дата продажи;

– ФИО менеджера.

14. Составить программу, которая обрабатывает информацию о заказе на пошив одежды в ателье.

Сведения о заказе содержат:

– номер заказа (ключ);

– предмет одежды;

– ФИО закройщика;

– стоимость материала.

15. Составить программу, которая обрабатывает информацию о продаже билетов на концерт.

– дата концерта (ключ);

– название исполнителя;

– количество проданных билетов.

16. Составить программу, которая обрабатывает информацию о продаже путевок в туристическом агентстве.

Сведения о туре содержат:

– название тура (ключ);

– продолжительность тура;

– стоимость путевки;

– количество проданных путевок.

17. Составить программу, которая обрабатывает информацию о пользователях компьютерной сети.

Сведения о пользователе содержат:

– логин пользователя(ключ);

– дата регистрации;

– тип пользователя.

18. Составить программу, которая обрабатывает информацию о продажах компьютерных игр.

Сведения о туре содержат:

– название игры (ключ);

– издатель;

– количество проданных физических копий;

– количество проданных цифровых копий.

19. Составить программу, которая обрабатывает информацию о гостиничных номерах.

Сведения о номере содержат:

– номер комнаты (ключ);

– этаж;

– вид номера;

– количество мест.

20. Составить программу, которая обрабатывает информацию о таксопарке.

Сведения о такси содержат:

– номер машины (ключ);

– ФИО водителя;

– марка машины;

– стаж водителя.

21. Составить программу, которая обрабатывает информацию об авиаполке.

Сведения об авиаполке содержат:

– номер полка (ключ);

– ФИО командира;

– количество самолетов;

– количество боеготовых самолетов.

22. Составить программу, которая обрабатывает информацию об учебной дисциплине.

Сведения об учебной дисциплине содержат:

– шифр дисциплины (ключ);

– название дисциплины;

– количество лекционных часов;

– количество часов на лабораторные работы.

23. Составить программу, которая обрабатывает информацию о товарах.

Сведения о товарах содержат:

– индекс товара (ключ);

– название товара;

– цена товара.

24. Составить программу, которая обрабатывает информацию о счетах.

Сведения о счете содержат:

– номер счета (ключ);

– ФИО клиента;

– годовой процент.

25. Составить программу, которая обрабатывает информацию о сотрудниках.

Сведения о сотруднике содержат:

– табельный номер (ключ);

– ФИО сотрудника;

– должность.

26. Составить программу, которая обрабатывает информацию о студентах.

Сведения о студенте содержат:

– номер зачетки (ключ);

– ФИО студента;

– группа.

27. Составить программу, которая обрабатывает информацию о файлах.

Сведения о файле содержат:

– название файла (ключ);

– тип файла;

– размер файла.

28. Составить программу, которая обрабатывает информацию об оборудовании.

Сведения об оборудовании содержат:

– серийный номер (ключ);

– название оборудования;

– тип оборудования;

– стоимость оборудования.

19