Добавил:
CanyonE
СПбГУТ * ИКСС * Программная инженерия
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Решения лабораторных работ (местами есть ошибки) / Lab5_2_Stack (singly linked list)
.cpp#include <iostream>
#include <stdexcept>
using std::cin;
using std::cout;
using std::endl;
// Стек на основе однонаправленного списка
template <class T>
class Stack {
protected:
struct stack {
size_t n;
T *elem;
stack *child;
};
private:
stack *data_ = nullptr;
public:
// Конструктор
Stack() = default;
// Конструктор копирования
Stack(const Stack &arg) {
if (arg.data_ && arg.data_->n > 0) {
stack *t = arg.data_;
T *temp = new T[arg.data_->n]; // Выделяем память под массив
for (size_t i = 0; i < arg.data_->n; ++i) {
temp[i] = *t->elem, t = t->child; // Добавляем очередной элемент стека в массив
}
for (size_t i = 0; i < arg.data_->n; ++i) {
push(temp[arg.data_->n - i - 1]); // Добавляем элементы массива с конца в стек
}
delete[] temp;
}
}
// Оператор копирования
Stack &operator=(const Stack &arg) {
Stack temp(arg);
swap(*this, temp);
return *this;
}
// Конструктор перемещения
Stack(Stack &&arg) noexcept {
data_ = arg.data_;
arg.data_ = nullptr;
}
// Оператор перемещения
Stack &operator=(Stack &&arg) noexcept {
if (this != &arg) {
swap(*this, arg);
arg.clear();
}
return *this;
}
// Деструктор
virtual ~Stack() {
clear();
}
// Очистка стека
void clear() {
if (data_) {
stack *child = data_->child;
while (child) {
delete child->elem;
stack *next = child->child;
delete child;
child = next;
}
delete data_, data_ = nullptr;
}
}
// Вставляет элемент на верх
Stack &push(const T &elem) {
if (data_) {
data_ = new stack {data_->n + 1, new T {elem}, data_};
return *this;
}
data_ = new stack {1, new T {elem}, nullptr};
return *this;
}
// Доступ к верхнему элементу
T &top() const noexcept(false) {
if (data_) {
return *data_->elem;
}
throw std::out_of_range("Stack. Method top. Out of range");
}
// Удаляет верхний элемент
void pop() noexcept(false) {
if (data_) {
delete data_->elem;
stack *child = data_->child;
delete data_;
data_ = child;
return;
}
throw std::out_of_range("Stack. Method pop. Out of range");
}
// Возвращает размер стека
size_t size() const {
if (data_) {
return data_->n;
}
return 0;
}
// True, если стек пустой, иначе False
bool empty() const noexcept {
return data_ == nullptr;
}
// Оператор приведения к типу bool
explicit operator bool() {
return data_ != nullptr;
}
// Вывод содержимого стека в поток ostream (cout, ...)
friend std::ostream &operator<<(std::ostream &os, const Stack &arg) {
stack *t = arg.data_;
if (t) {
os << t->n << ": [" << *t->elem << "]";
while (t->child) {
os << ' ' << t->child->n << ": [" << *t->child->elem << "]";
t = t->child;
}
}
return os;
}
friend void swap(Stack &first, Stack &second) noexcept {
std::swap(first.data_, second.data_);
}
};
int main() {
Stack<double> stackA, stackB;
// Добавление элементов на верх
stackA.push(111).push(222).push(333).push(444);
stackB.push(444).push(555).push(666);
// Отображение содержимого стеков
cout << "Stack A: " << stackA << endl;
cout << "Stack B: " << stackB << endl;
// Доступ к вершине стека и удаление верхнего элемента
cout << "Stack A [top(), pop()]: " << stackA.top() << endl;
stackA.pop();
cout << "Stack B [top(), pop()]: " << stackB.top() << endl;
stackB.pop();
// Конструктор копирования
Stack<double> stackC(stackA);
cout << "Stack (after copy): " << stackA << " (top: " << stackA.top() << ")\n";
cout << "Copy ^ (constructor): " << stackC << " (top: " << stackC.top() << ")\n";
// Оператор копирования
stackC = stackB;
cout << "Stack (after copy): " << stackB << " (top: " << stackB.top() << ")\n";
cout << "Copy ^ (assignment): " << stackC << " (top: " << stackC.top() << ")\n";
// Конструктор перемещения
Stack<double> stackD(std::move(stackA));
cout << "Stack (after move): " << stackA << endl;
cout << "Move ^ (constructor): " << stackD << " (top: " << stackD.top() << ")\n";
// Оператор перемещения
stackC = std::move(stackB);
cout << "Stack (after move): " << stackB << endl;
cout << "Move ^ (assignment): " << stackC << " (top: " << stackC.top() << ")\n";
// Размер стека
cout << "Stack D (size): " << stackD.size() << " (isEmpty ? " << ( stackD.empty() ? "TRUE" : "FALSE" ) << ")\n";
cout << "Stack C (size): " << stackC.size() << " (isEmpty ? " << ( stackC.empty() ? "TRUE" : "FALSE" ) << ")\n";
stackD.pop(), stackD.pop(), stackD.pop();
stackC.clear();
cout << "Stack D (size after pop): " << stackD.size() << " (isEmpty ? " << ( stackD.empty() ? "TRUE" : "FALSE" )
<< ")\n";
cout << "Stack C (size after pop): " << stackC.size() << " (isEmpty ? " << ( stackC.empty() ? "TRUE" : "FALSE" )
<< ")\n";
// Работа деструктора...
stackD.push(5).push(6).push(7);
}
Соседние файлы в папке Решения лабораторных работ (местами есть ошибки)