35657

Untitled

Jul 19th, 2023
804
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.36 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 (size == 0) {
  136.             throw runtime_error("Обращение к пустому контейнеру");
  137.         }
  138.         return head->value;
  139.     }
  140.                                                                          
  141.     const T& Front() const {
  142.         if (size == 0) {
  143.             throw runtime_error("Обращение к пустому контейнеру");
  144.         }
  145.         return head->value;
  146.     }
  147.  
  148.     T& Back() {
  149.         if (size == 0) {
  150.             throw runtime_error("Обращение к пустому контейнеру");
  151.         }
  152.         return last->value;
  153.     }
  154.  
  155.     const T& Back() const {
  156.         if (size == 0) {
  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.        
  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.     void Erase(const int index) {
  196.         if (index < 0 || index >= size) {
  197.             throw logic_error("Невалидный индекс");
  198.         }
  199.         if (index == 0) {
  200.             Pop_front();
  201.             return;
  202.         }
  203.         if (index == size - 1) {
  204.             Pop_back();
  205.             return;
  206.         }
  207.         Node* temp = head;
  208.         for (int i = 0; i < index - 1; i++) {
  209.             temp = temp->next;
  210.         }
  211.         Node* buf = temp->next->next;
  212.         delete temp->next;
  213.         temp->next = buf;
  214.         temp->next->prev = temp;
  215.         size--;
  216.     }
  217.  
  218.     bool operator==(const List& other) {
  219.         if (this->size != other.size) {
  220.             return false;
  221.         }
  222.         Node* temp = head;
  223.         Node* other_temp = other.head;
  224.         while (temp != nullptr) {
  225.             if (temp->value != other_temp->value) {
  226.                 return false;
  227.             }
  228.             temp = temp->next;
  229.             other_temp = other_temp->next;
  230.         }
  231.         return true;
  232.     }
  233.  
  234.     bool operator!=(const List& other) {
  235.         return !(*this == other);
  236.     }
  237.  
  238.     T& operator[] (const int index) {
  239.         if (index < 0 || index >= size) {
  240.             throw logic_error("Невалидный индекс");
  241.         }
  242.         Node* temp = head;
  243.         for (int i = 0; i < index; i++) {
  244.             temp = temp->next;
  245.         }
  246.         return temp->value;
  247.     }
  248.  
  249.     const T& operator[] (const int index) const {
  250.         if (index < 0 || index >= size) {
  251.             throw logic_error("Невалидный индекс");
  252.         }
  253.         Node* temp = head;
  254.         for (int i = 0; i < index; i++) {
  255.             temp = temp->next;
  256.         }
  257.         return temp->value;
  258.     }
  259.  
  260.     int Find(const T& value) {
  261.         if (size == 0) {
  262.             throw runtime_error("Попытка удаления в пустом контейнере");
  263.         }
  264.         int i = 0;
  265.         Node* temp = head;
  266.         while (temp != nullptr && temp->value != value) {
  267.             temp = temp->next;
  268.             i++;
  269.         }
  270.         if (temp != nullptr) {
  271.             return i;
  272.         }
  273.         return -1;
  274.     }
  275.  
  276.     ~List() {
  277.         Clear();
  278.     }
  279.  
  280. private:
  281.     struct Node { // двусвязный список состоит из узлов
  282.         T value; // узел хранит информативную часть
  283.         Node* next; // указатель на следующий узел в списке
  284.         Node* prev; // указатель на предыдущий узел
  285.     };
  286.  
  287.     int size = 0;
  288.     Node* head = nullptr;
  289.     Node* last = nullptr;
  290. };
  291.  
  292. int main() {
  293.  
  294.     setlocale(LC_ALL, "ru");
  295.  
  296.     try {
  297.  
  298.         List<int> list1;
  299.  
  300.         list1.Insert(12, 10);
  301.  
  302.         for (int i = 0; i < 10; i++) {
  303.             list1.Push_front(i + 1);
  304.             list1.Print();
  305.         }
  306.         cout << list1.Size() << endl;
  307.  
  308.         for (int i = 0; i < 3; i++) {
  309.             list1.Pop_front();
  310.             list1.Print();
  311.         }
  312.         cout << list1.Size() << endl;
  313.  
  314.         cout << "Front: " << list1.Front() << " Back: " << list1.Back() << endl;
  315.  
  316.         list1.Push_back(10);
  317.         list1.Print();
  318.         list1.Pop_back();
  319.         list1.Print();
  320.  
  321.         cout << "list2: " << endl;
  322.         List<int> list2(move(list1));
  323.         list2.Print();
  324.  
  325.         cout << "list1: " << endl;
  326.         list1.Print();
  327.  
  328.         list2.Insert(3, 12);
  329.         cout << "list2: " << endl;
  330.         list2.Print();
  331.  
  332.         list2.Erase(2);
  333.         list2.Print();
  334.         cout << list2.Find(12) << endl;
  335.         cout << boolalpha << (list1 == list2) << endl;
  336.         cout << (list1 != list2) << endl;
  337.  
  338.         cout << list2[3] << endl;
  339.         list2[3] = 10;
  340.         list2.Print();
  341.  
  342.     }
  343.     catch (const logic_error& ex) {
  344.         cout << ex.what() << endl;
  345.     }
  346.     catch (const runtime_error& ex) {
  347.         cout << ex.what() << endl;
  348.     }
  349.     catch (const bad_alloc &ex) {
  350.         cout << "Ошибка выделения динамической памяти" << endl;
  351.     }
  352.     catch (...) {
  353.         cout << "Другая ошибка" << endl;
  354.     }
  355. }
Advertisement
Add Comment
Please, Sign In to add comment