- •Міністерство освіти та науки україни
- •Аннотация
- •Анотація
- •Лабораторная работа 1 “Одномерный массив - вектор”
- •1. Общие указания
- •2. Пример реализации
- •3. Варианты задания
- •4. Требования к отчету
- •2. Пример реализации
- •3. Варианты задания
- •4. Требования к отчету
- •1.2. Динамические структуры данных: стек, очередь список
- •2. Пример реализации
- •4.Варианты заданий
- •Порядок выполнения работы.
- •Лабораторная работа №4 “Обработка строк”
- •1. Общие указания
- •2.1. Функции ввода/вывода строк
- •2.2. Другие функции работы со строками
- •3. Пример реализации класса «строка»
- •3.1. Класс Слово (word)(строка в одно слово)
- •3.2. Класс Сообщение (Message)(строка длиной до 80 символов (одна экранная строка)
- •3.3. Класс Предложение (sentence) (Строка, состоящая из одного Предложения, занимающего одну или более строк)
- •4. Варианты задания
- •5. Требования к отчету
- •2. Варианты задания
- •3. Содержание отчета
- •Лабораторная работа 6 “Множественное наследование”
- •1. Общие указания
- •4.Варианты заданий
- •Приложение b Терминологический словарь
2. Пример реализации
ЗАДАНИЕ 1: Данный пример демонстрирует создание и реализацию функций двусвязного списка. Код функции main лишь описывает пример применения функций класса.
list.h
#ifndef _LIST_
#define _LIST_
struct Elem // элемент списка
{
int data; // данные
Elem * next, * prev;
};
class List
{
Elem * Head, * Tail; // Голова, хвост
int Count; // Количество элементов
public:
List();// Конструктор
List(const List&);// Конструктор копирования
~List();// Деструктор
int GetCount(); // Получить количество
Elem* GetElem(int); // Получить элемент списка по номеру
void DelAll(); // Удалить весь список
void Del(int pos = 0); // Удаление элемента, если параметр не указывается,
// то функция его запрашивает
void Insert(int pos = 0); // Вставка элемента, если параметр не указывается,
// то функция его запрашивает
void AddTail(int n); // Добавление в конец списка
void AddHead(int n); // Добавление в начало списка
void Print();// Печать списка
void Print(int pos); // Печать заданного элемента
//************ Перегрузка**************//
List& operator = (const List&);
List operator + (const List&);// сложение двух списков (дописывание)
// сравнение по элементам
bool operator == (const List&);
bool operator != (const List&);
bool operator <= (const List&);
bool operator >= (const List&);
bool operator < (const List&);
bool operator > (const List&);
List operator - (); // переворачивание списка
};
#endif
list.cpp
#include <iostream.h>
#include "List.h"
List::List()
{// Изначально список пуст
Head = Tail = NULL;
Count = 0;
}
List::List(const List & L)
{
Head = Tail = NULL;
Count = 0;
Elem *temp = L.Head; // Голова списка, из которого копируем
while(temp != 0) // Пока не конец списка
{
AddTail(temp->data); // Копируем данные
temp = temp->next;
}
}
List::~List()
{
DelAll();// Удаляем все элементы
}
void List::AddHead(int n)
{
Elem * temp = new Elem; // новый элемент
temp->prev = 0; // Предыдущего нет
temp->data = n; // Заполняем данные
temp->next = Head; // Следующий - бывшая голова
if(Head != 0) // Если элементы есть
Head->prev = temp;
if(Count == 0) // Если элемент первый, то он одновременно и голова и хвост
Head = Tail = temp;
else
// иначе новый элемент - головной
Head = temp;
Count++;
}
void List::AddTail(int n)
{
Elem * temp = new Elem; // Создаем новый элемент
temp->next = 0; // Следующего нет
temp->data = n; // Заполняем данные
temp->prev = Tail; // Предыдущий - бывший хвост
if(Tail != 0) // Если элементы есть
Tail->next = temp;
// Если элемент первый, то он одновременно и голова и хвост
if(Count == 0)
Head = Tail = temp;
else
Tail = temp; // иначе новый элемент - хвостовой
Count++;
}
void List::Insert(int pos)
{
// если параметр отсутствует или равен 0, то запрашиваем его
if(pos == 0)
{
cout << "Input position: ";
cin >> pos;
}
if(pos < 1 || pos > Count + 1) // Позиция от 1 до Count
{
cout << "Incorrect position !!!\n"; // Неверная позиция
return;
}
if(pos == Count + 1) // Если вставка в конец списка
{
int data; // Вставляемые данные
cout << "Input new number: ";
cin >> data; // Добавление в конец списка
AddTail(data);
return;
}
else if(pos == 1)
{
int data; // Вставляемые данные
cout << "Input new number: ";
cin >> data; // Добавление в начало списка
AddHead(data);
return;
}
int i = 1; // Счетчик
Elem * Ins = Head; // Отсчитываем от головы n - 1 элементов
while(i < pos)
{
// Доходим до элемента, перед которым вставляемся
Ins = Ins->next;
i++;
}
// Доходим до элемента, который предшествует
Elem * PrevIns = Ins->prev;
Elem * temp = new Elem; // Создаем новый элемент
cout << "Input new number: "; // Вводим данные
cin >> temp->data;
if(PrevIns != 0 && Count != 1) // настройка связей
PrevIns->next = temp;
temp->next = Ins;
temp->prev = PrevIns;
Ins->prev = temp;
Count++;
}
void List::Del(int pos)
{
if(pos == 0) // если параметр отсутствует или равен 0, то запрашиваем его
{
cout << "Input position: ";
cin >> pos;
}
if(pos < 1 || pos > Count) // Позиция от 1 до Count
{
cout << "Incorrect position !!!\n"; // Неверная позиция
return;
}
int i = 1; // Счетчик
Elem *Del = Head;
while(i < pos)
{
// Доходим до элемента, который удаляется
Del = Del->next;
i++;
}
// Доходим до элемента, который предшествует удаляемому
Elem * PrevDel = Del->prev;
// Доходим до элемента, который следует за удаляемым
Elem * AfterDel = Del->next;
if(PrevDel != 0 && Count != 1) // Если удаляем не голову
PrevDel->next = AfterDel;
if(AfterDel != 0 && Count != 1) // Если удаляем не хвост
AfterDel->prev = PrevDel;
if(pos == 1) // Удаляются крайние?
Head = AfterDel;
if(pos == Count)
Tail = PrevDel;
delete Del; // Удаление элемента
Count--;
}
void List::Print(int pos)
{
if(pos < 1 || pos > Count) // Позиция от 1 до Count
{
cout << "Incorrect position !!!\n"; // Неверная позиция
return;
}
Elem * temp;
if(pos <= Count / 2) // Определяем с какой стороны быстрее двигаться
{
temp = Head; // Отсчет с головы
int i = 1;
while(i < pos)
{
temp = temp->next; // Двигаемся до нужного элемента
i++;
}
}
else
{
temp = Tail; // Отсчет с хвоста
int i = 1;
while(i <= Count - pos)
{
temp = temp->prev; // Двигаемся до нужного элемента
i++;
}
}
cout << pos << " element: ";// Вывод элемента
cout << temp->data << endl;
}
void List::Print()
{
// Если в списке присутствуют элементы, то пробегаем по нему
// и печатаем элементы, начиная с головного
if(Count != 0)
{
Elem * temp = Head;
cout << "( ";
while(temp->next != 0)
{
cout << temp->data << ", ";
temp = temp->next;
}
cout << temp->data << " )\n";
}
}
void List::DelAll()
{
while(Count != 0) // Пока остаются элементы, удаляем по одному с головы
Del(1);
}
int List::GetCount()
{
return Count;
}
Elem * List::GetElem(int pos)
{
Elem *temp = Head;
if(pos < 1 || pos > Count) // Позиция от 1 до Count?
{
cout << "Incorrect position !!!\n"; // Неверная позиция
return;
}
int i = 1;
while(i < pos && temp != 0) // Ищем нужный нам элемент
{
temp = temp->next;
i++;
}
if(temp == 0)
return 0;
else
return temp;
}
List& List::operator = (const List & L)
{
if(this == &L) // Проверка присваивания элемента "самому себе"
return *this;
// удаление старого списка
this->~List(); // деструктор вызывает DelAll();
Elem * temp = L.Head;
while(temp != 0) // Копируем элементы
{
AddTail(temp->data);
temp = temp->next;
}
return *this;
}
List List::operator + (const List& L) // сложение двух списков
{
// Заносим во временный список элементы первого списка
List Result(*this); // List Result = *this;
Elem * temp = L.Head;
while(temp != 0) // Добавляем во временный список элементы второго списка
{
Result.AddTail(temp->data);
temp = temp->next;
}
return Result;
}
bool List::operator == (const List& L)
{
if(Count != L.Count) // Сравнение по количеству
return false;
Elem *t1, *t2;
t1 = Head;
t2 = L.Head;
while(t1 != 0) // Сравнение по содержанию
{
// Сверяем данные, которые находятся на одинаковых позициях
if(t1->data != t2->data)
return false;
t1 = t1->next;
t2 = t2->next;
}
return true;
}
bool List::operator != (const List& L)
{
return !(*this == L); // Используем предыдущую функцию сравнения
}
bool List::operator >= (const List& L)
{
if(Count > L.Count) // Сравнение по количеству
return true;
if(*this == L) // Сравнение по содержанию
return true;
return false;
}
bool List::operator <= (const List& L)
{
if(Count < L.Count) // Сравнение по количеству
return true;
if(*this == L) // Сравнение по содержанию
return true;
return false;
}
bool List::operator > (const List& L)
{
if(Count > L.Count)
return true;
return false;
}
bool List::operator < (const List& L)
{
if(Count < L.Count)
return true;
return false;
}
List List::operator - ()// переворот
{
List Result;
Elem * temp = Head;
// Копируем элементы списка, начиная с головного,
// в свой путем добавления элементов в голову,
// таким образом, временный список Result будет содержать
// элементы в обратном порядке
while(temp != 0)
{
Result.AddHead(temp->data);
temp = temp->next;
}
return Result;
}
main_li.cpp
#include <iostream.h>
#include "list.cpp"
void main()// Тестовый пример
{
List L;
const n = 10;
int a[n] = {0,1,2,3,4,5,6,7,8,9};
// Добавляем элементы, стоящие на четных индексах, в голову,
// на нечетных - в хвост
for(int i = 0; i < n; i++)
if(i % 2 == 0)
L.AddHead(a[i]);
else
L.AddTail(a[i]);
cout << "List L:\n"; // Распечатка списка
L.Print();
cout << endl;
L.Insert();// Вставка элемента в список
cout << "List L:\n";// Распечатка списка
L.Print();
// Распечатка 2-го и 8-го элементов списка
L.Print(2);
L.Print(8);
List T;
T = L; // Копируем список
cout << "List T:\n";// Распечатка копии
T.Print();
// Складываем два списка (первый в перевернутом состоянии)
cout << "List Sum:\n";
List Sum = -L + T;
// Распечатка списка
Sum.Print();}