Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- using namespace std;
- template<typename T>
- class List {
- public:
- List() : size(0), head(nullptr), last(nullptr) {}
- List(const initializer_list<T>& list) : size(0), head(nullptr), last(nullptr) {
- for (const auto& element : list) {
- Push_back(element);
- }
- }
- List(const List& other) : size(other.size), head(nullptr), last(nullptr) {
- if (other.head != nullptr) {
- head = new Node{ other.head->value, nullptr, nullptr };
- Node* temp = head;
- Node* other_temp = other.head;
- while (other_temp->next != nullptr) {
- other_temp = other_temp->next;
- temp->next = new Node{ other_temp->value, nullptr, temp };
- temp = temp->next;
- }
- last = temp;
- }
- }
- List(List&& other) : size(other.size), head(other.head), last(other.last) {
- other.size = 0;
- other.head = nullptr;
- other.last = nullptr;
- }
- List& operator=(const List& other) {
- if (this != &other) {
- Clear();
- if (other.head != nullptr) {
- head = new Node{ other.head->value, nullptr, nullptr };
- Node* temp = head;
- Node* other_temp = other.head;
- while (other_temp->next != nullptr) {
- other_temp = other_temp->next;
- temp->next = new Node{ other_temp->value, nullptr, temp };
- temp = temp->next;
- }
- last = temp;
- size = other.size;
- }
- }
- return *this;
- }
- List& operator=(List&& other) {
- if (this != &other) {
- Clear();
- size = other.size;
- head = other.head;
- last = other.last;
- other.size = 0;
- other.head = nullptr;
- other.last = nullptr;
- }
- return *this;
- }
- void Push_front(const T& value) {
- if (size == 0) {
- last = head = new Node{ value, nullptr, nullptr };
- size++;
- return;
- }
- Node* temp = new Node{ value, head, nullptr };
- head->prev = temp;
- head = temp;
- size++;
- }
- void Push_back(const T& value) {
- if (size == 0) {
- last = head = new Node{ value, nullptr, nullptr };
- size++;
- return;
- }
- Node* temp = new Node{ value, nullptr, last };
- last->next = temp;
- last = temp;
- size++;
- }
- void Pop_front() {
- if (size == 0) {
- throw runtime_error("Попытка удаления в пустом контейнере");
- }
- if (size == 1) {
- delete head;
- last = head = nullptr;
- size--;
- return;
- }
- head = head->next;
- delete head->prev;
- head->prev = nullptr;
- size--;
- }
- void Pop_back() {
- if (size == 0) {
- throw runtime_error("Попытка удаления в пустом контейнере");
- }
- if (size == 1) {
- delete head;
- last = head = nullptr;
- size--;
- return;
- }
- last = last->prev;
- delete last->next;
- last->next = nullptr;
- size--;
- }
- void Print() const {
- Node* temp = head;
- while (temp != nullptr) {
- cout << temp->value << " ";
- temp = temp->next;
- }
- cout << endl;
- }
- T& Front() {
- if (head == nullptr) {
- throw runtime_error("Обращение к пустому контейнеру");
- }
- return head->value;
- }
- const T& Front() const {
- if (head == nullptr) {
- throw runtime_error("Обращение к пустому контейнеру");
- }
- return head->value;
- }
- T& Back() {
- if (last == nullptr) {
- throw runtime_error("Обращение к пустому контейнеру");
- }
- return last->value;
- }
- const T& Back() const {
- if (last == nullptr) {
- throw runtime_error("Обращение к пустому контейнеру");
- }
- return last->value;
- }
- int Size() const {
- return size;
- }
- void Clear() {
- while (head != nullptr) {
- Pop_front();
- }
- }
- void Insert(const int index, const int& value) {
- if (index < 0 || index > size) {
- throw logic_error("Невалидный индекс");
- }
- if (index == 0) {
- Push_front(value);
- return;
- }
- if (index == size) {
- Push_back(value);
- return;
- }
- Node* temp = head;
- for (int i = 0; i < index - 1; i++) {
- temp = temp->next;
- }
- Node* node = new Node{ value, temp->next, temp };
- temp->next->prev = node;
- temp->next = node;
- size++;
- }
- void Erase(const int index) {
- if (index < 0 || index >= size) {
- throw logic_error("Невалидный индекс");
- }
- if (index == 0) {
- Pop_front();
- return;
- }
- if (index == size) {
- Pop_back();
- return;
- }
- Node* temp = head;
- for (int i = 0; i < index - 1; i++) {
- temp = temp->next;
- }
- Node* buf = temp->next->next;
- delete temp->next;
- temp->next = buf;
- temp->next->prev = temp;
- size--;
- }
- bool operator==(const List& other) {
- if (this->size != other.size) {
- return false;
- }
- Node* temp = head;
- Node* other_temp = other.head;
- while (temp != nullptr) {
- if (temp->value != other_temp->value) {
- return false;
- }
- temp = temp->next;
- other_temp = other_temp->next;
- }
- return true;
- }
- bool operator!=(const List& other) {
- return !(*this == other);
- }
- T& operator[] (const int index) {
- if (index < 0 || index >= size) {
- throw logic_error("Невалидный индекс");
- }
- Node* temp = head;
- for (int i = 0; i < index; i++) {
- temp = temp->next;
- }
- return temp->value;
- }
- const T& operator[] (const int index) const {
- if (index < 0 || index >= size) {
- throw logic_error("Невалидный индекс");
- }
- Node* temp = head;
- for (int i = 0; i < index; i++) {
- temp = temp->next;
- }
- return temp->value;
- }
- int Find(const T & value) {
- if (size == 0) {
- throw runtime_error("Попытка поиска в пустом контейнере");
- }
- int i = 0;
- Node* temp = head;
- while (temp != nullptr && temp->value != value) {
- temp = temp->next;
- i++;
- }
- if (temp != nullptr) {
- return i;
- }
- return -1;
- }
- ~List() {
- Clear();
- }
- private:
- struct Node { // двусвязный список состоит из узлов
- T value; // узел хранит информативную часть
- Node* next; // указатель на следующий узел в списке
- Node* prev; // указатель на предыдущий узел
- };
- int size = 0;
- Node* head = nullptr;
- Node* last = nullptr;
- };
- int main() {
- setlocale(LC_ALL, "ru");
- try {
- List<int> list1;
- for (int i = 0; i < 10; i++) {
- list1.Push_front(i + 1);
- list1.Print();
- }
- cout << list1.Size() << endl;
- for (int i = 0; i < 3; i++) {
- list1.Pop_front();
- list1.Print();
- }
- cout << list1.Size() << endl;
- cout << "Front: " << list1.Front() << " Back: " << list1.Back() << endl;
- list1.Push_back(10);
- list1.Print();
- list1.Pop_back();
- list1.Print();
- cout << "list2: " << endl;
- List<int> list2(move(list1));
- list2.Print();
- cout << "list1: " << endl;
- list1.Print();
- list2.Insert(3, 12);
- cout << "list2: " << endl;
- list2.Print();
- list2.Erase(2);
- list2.Print();
- cout << list2.Find(12) << endl;
- cout << boolalpha << (list1 == list2) << endl;
- cout << (list1 != list2) << endl;
- cout << list2[3] << endl;
- list2[3] = 10;
- list2.Print();
- }
- catch (const logic_error & ex) {
- cout << ex.what() << endl;
- }
- catch (const runtime_error & ex) {
- cout << ex.what() << endl;
- }
- catch (const bad_alloc & ex) {
- cout << "Ошибка выделения динамической памяти" << endl;
- }
- catch (...) {
- cout << "Другая ошибка" << endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment