35657

Untitled

Jul 28th, 2023
1,223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.54 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. template<typename T>
  6. class List {
  7. public:
  8.  
  9.     List() : size(0), head(nullptr), last(nullptr) {}
  10.  
  11.     List(const initializer_list<T>& list) : size(0), head(nullptr), last(nullptr) {
  12.         for (const auto& element : list) {
  13.             Push_back(element);
  14.         }
  15.     }
  16.  
  17.     List(const List& other) : size(other.size), head(nullptr), last(nullptr) {
  18.         if (other.head != nullptr) {
  19.             head = new Node{ other.head->value, nullptr, nullptr };
  20.             Node* temp = head;
  21.             Node* other_temp = other.head;
  22.             while (other_temp->next != nullptr) {
  23.                 other_temp = other_temp->next;
  24.                 temp->next = new Node{ other_temp->value, nullptr, temp };
  25.                 temp = temp->next;
  26.             }
  27.             last = temp;
  28.         }
  29.     }
  30.  
  31.     List(List&& other) : size(other.size), head(other.head), last(other.last) {
  32.         other.size = 0;
  33.         other.head = nullptr;
  34.         other.last = nullptr;
  35.     }
  36.  
  37.     List& operator=(const List& other) {
  38.         if (this != &other) {
  39.             Clear();
  40.             if (other.head != nullptr) {
  41.                 head = new Node{ other.head->value, nullptr, nullptr };
  42.                 Node* temp = head;
  43.                 Node* other_temp = other.head;
  44.                 while (other_temp->next != nullptr) {
  45.                     other_temp = other_temp->next;
  46.                     temp->next = new Node{ other_temp->value, nullptr, temp };
  47.                     temp = temp->next;
  48.                 }
  49.                 last = temp;
  50.                 size = other.size;
  51.             }
  52.         }
  53.         return *this;
  54.     }
  55.  
  56.     List& operator=(List&& other) {
  57.         if (this != &other) {
  58.             Clear();
  59.             size = other.size;
  60.             head = other.head;
  61.             last = other.last;
  62.             other.size = 0;
  63.             other.head = nullptr;
  64.             other.last = nullptr;
  65.         }
  66.         return *this;
  67.     }
  68.  
  69.     void Push_front(const T& value) {
  70.         if (size == 0) {
  71.             last = head = new Node{ value, nullptr, nullptr };
  72.             size++;
  73.             return;
  74.         }
  75.         Node* temp = new Node{ value, head, nullptr };
  76.         head->prev = temp;
  77.         head = temp;
  78.         size++;
  79.     }
  80.  
  81.     void Push_back(const T& value) {
  82.         if (size == 0) {
  83.             last = head = new Node{ value, nullptr, nullptr };
  84.             size++;
  85.             return;
  86.         }
  87.         Node* temp = new Node{ value, nullptr, last };
  88.         last->next = temp;
  89.         last = temp;
  90.         size++;
  91.     }
  92.  
  93.     void Pop_front() {
  94.         if (size == 0) {
  95.             throw runtime_error("Попытка удаления в пустом контейнере");
  96.         }
  97.         if (size == 1) {
  98.             delete head;
  99.             last = head = nullptr;
  100.             size--;
  101.             return;
  102.         }
  103.         head = head->next;
  104.         delete head->prev;
  105.         head->prev = nullptr;
  106.         size--;
  107.     }
  108.  
  109.     void Pop_back() {
  110.         if (size == 0) {
  111.             throw runtime_error("Попытка удаления в пустом контейнере");
  112.         }
  113.         if (size == 1) {
  114.             delete head;
  115.             last = head = nullptr;
  116.             size--;
  117.             return;
  118.         }
  119.         last = last->prev;
  120.         delete last->next;
  121.         last->next = nullptr;
  122.         size--;
  123.     }
  124.  
  125.     void Print() const {
  126.         Node* temp = head;
  127.         while (temp != nullptr) {
  128.             cout << temp->value << " ";
  129.             temp = temp->next;
  130.         }
  131.         cout << endl;
  132.     }
  133.  
  134.     T& Front() {
  135.         if (head == nullptr) {
  136.             throw runtime_error("Обращение к элементу пустого контейнера");
  137.         }
  138.         return head->value;
  139.     }
  140.  
  141.     const T& Front() const {
  142.         if (head == nullptr) {
  143.             throw runtime_error("Обращение к элементу пустого контейнера");
  144.         }
  145.         return head->value;
  146.     }
  147.  
  148.     T& Back() {
  149.         if (last == nullptr) {
  150.             throw runtime_error("Обращение к элементу пустого контейнера");
  151.         }
  152.         return last->value;
  153.     }
  154.  
  155.     const T& Back() const {
  156.         if (last == nullptr) {
  157.             throw runtime_error("Обращение к элементу пустого контейнера");
  158.         }
  159.         return last->value;
  160.     }
  161.  
  162.     int Size() const {
  163.         return size;
  164.     }
  165.  
  166.     void Clear() {
  167.         while (head != nullptr) {
  168.             Pop_front();
  169.         }
  170.     }
  171.  
  172.     void Insert(const int index, const int& value) {
  173.         if (index < 0 || index > size) {
  174.             throw logic_error("Невалидный индекс");
  175.         }
  176.         if (index == 0) {
  177.             Push_front(value);
  178.             return;
  179.         }
  180.         if (index == size) {
  181.             Push_back(value);
  182.             return;
  183.         }
  184.         if (index > 0 && index < size) {
  185.             Node* temp = head;
  186.             for (int i = 0; i < index - 1; i++) {
  187.                 temp = temp->next;
  188.             }
  189.             Node* node = new Node{ value, temp->next, temp };
  190.             temp->next->prev = node;
  191.             temp->next = node;
  192.             size++;
  193.         }
  194.     }
  195.  
  196.     void Erase(const int index) {
  197.         if (index < 0 || index >= size) {
  198.             throw logic_error("Невалидный индекс");
  199.         }
  200.         if (index == 0) {
  201.             Pop_front();
  202.             return;
  203.         }
  204.         if (index == size) {
  205.             Pop_back();
  206.             return;
  207.         }
  208.         if (index > 0 && index < size) {
  209.             Node* temp = head;
  210.             for (int i = 0; i < index - 1; i++) {
  211.                 temp = temp->next;
  212.             }
  213.             Node* buf = temp->next->next;
  214.             delete temp->next;
  215.             temp->next = buf;
  216.             temp->next->prev = temp;
  217.             size--;
  218.         }
  219.     }
  220.  
  221.     bool operator==(const List& other) {
  222.         if (this->size != other.size) {
  223.             return false;
  224.         }
  225.         Node* temp = head;
  226.         Node* other_temp = other.head;
  227.         while (temp != nullptr) {
  228.             if (temp->value != other_temp->value) {
  229.                 return false;
  230.             }
  231.             temp = temp->next;
  232.             other_temp = other_temp->next;
  233.         }
  234.         return true;
  235.     }
  236.  
  237.     bool operator!=(const List& other) {
  238.         return !(*this == other);
  239.     }
  240.  
  241.     T& operator[] (const int index) {
  242.         if (index < 0 || index >= size) {
  243.             throw logic_error("Невалидный индекс");
  244.         }
  245.         Node* temp = head;
  246.         for (int i = 0; i < index; i++) {
  247.             temp = temp->next;
  248.         }
  249.         return temp->value;
  250.     }
  251.  
  252.     const T& operator[] (const int index) const {
  253.         if (index < 0 || index >= size) {
  254.             throw logic_error("Невалидный индекс");
  255.         }
  256.         Node* temp = head;
  257.         for (int i = 0; i < index; i++) {
  258.             temp = temp->next;
  259.         }
  260.         return temp->value;
  261.     }
  262.  
  263.     int Find(const T& value) {
  264.         if (size == 0) {
  265.             throw runtime_error("Попытка поиска в пустом контейнере");
  266.         }
  267.         int i = 0;
  268.         Node* temp = head;
  269.         while (temp != nullptr && temp->value != value) {
  270.             temp = temp->next;
  271.             i++;
  272.         }
  273.         if (temp != nullptr) {
  274.             return i;
  275.         }
  276.         return -1;
  277.     }
  278.  
  279.     ~List() {
  280.         Clear();
  281.     }
  282.  
  283. private:
  284.     struct Node { // двусвязный список состоит из узлов
  285.         T value; // узел хранит информативную часть
  286.         Node* next; // указатель на следующий узел в списке
  287.         Node* prev; // указатель на предыдущий узел
  288.     };
  289.  
  290.     int size = 0;
  291.     Node* head = nullptr;
  292.     Node* last = nullptr;
  293. };
  294.  
  295. int main() {
  296.  
  297.     setlocale(LC_ALL, "ru");
  298.  
  299.     try {
  300.  
  301.         List<int> list1;
  302.  
  303.         //list1.Pop_back();
  304.  
  305.         for (int i = 0; i < 10; i++) {
  306.             list1.Push_front(i + 1);
  307.             list1.Print();
  308.         }
  309.         cout << list1.Size() << endl;
  310.  
  311.         for (int i = 0; i < 3; i++) {
  312.             list1.Pop_front();
  313.             list1.Print();
  314.         }
  315.         cout << list1.Size() << endl;
  316.  
  317.         cout << "Front: " << list1.Front() << " Back: " << list1.Back() << endl;
  318.  
  319.         list1.Push_back(10);
  320.         list1.Print();
  321.         list1.Pop_back();
  322.         list1.Print();
  323.  
  324.         cout << "list2: " << endl;
  325.         List<int> list2(move(list1));
  326.         list2.Print();
  327.  
  328.         cout << "list1: " << endl;
  329.         list1.Print();
  330.  
  331.         list2.Insert(3, 12);
  332.         cout << "list2: " << endl;
  333.         list2.Print();
  334.  
  335.         list2.Erase(2);
  336.         list2.Print();
  337.         cout << list2.Find(12) << endl;
  338.         cout << boolalpha << (list1 == list2) << endl;
  339.         cout << (list1 != list2) << endl;
  340.  
  341.         cout << list2[3] << endl;
  342.         list2[3] = 10;
  343.         list2.Print();
  344.  
  345.     }
  346.     catch (const logic_error& ex) {
  347.         cout << "1 " << ex.what() << endl;
  348.     }
  349.     catch (const runtime_error& ex) {
  350.         cout << "2 " << ex.what() << endl;
  351.     }
  352.     catch (const bad_alloc& ex) {
  353.         cout << "3 Ошибка выделения динамической памяти" << endl;
  354.     }
  355.     catch (...) {
  356.         cout << "4 Другая ошибка" << endl;
  357.     }
  358. }
Advertisement
Add Comment
Please, Sign In to add comment