35657

Untitled

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