constk

Суслик-шизоид

Sep 21st, 2021
652
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #pragma once
  2.  
  3. #include "List.h"
  4.  
  5. template <typename Type>
  6. ref class CyclicDoubleList : public List<Type>
  7. {
  8.     template <typename Type>
  9.     ref struct Node
  10.     {
  11.         Type data;
  12.         Node^ next = nullptr;
  13.         Node^ prev = nullptr;
  14.     };
  15.  
  16. public:
  17.     CyclicDoubleList();
  18.     ~CyclicDoubleList();
  19.  
  20.     void Print(System::Windows::Forms::ListBox^ listBoxForPrint) override; // печать списка
  21.  
  22.     void InsertToBegin(Type) override; // вставка в начало
  23.     void Insert(Type, int) override; // вставка после элемента с указанным индексом
  24.  
  25.     void Delete(int) override; // удаление элемента с указанным индексом
  26.     void Clear() override; // удаление всего списка
  27.  
  28.     int Find(Type) override; // поиск элемента
  29.     Type At(int) override; // возвращает элемент с указанным индексом
  30.     bool IsEmpty() override; // проверка списка на пустоту
  31.     int Size() override; // возвращает размер списка
  32.  
  33. protected:
  34.     void CreateFirst(Type) override; // создать первый элемент списка
  35.  
  36.     Node<Type>^ head = nullptr; // указатель на начало списка
  37.     Node<Type>^ current = nullptr; // указатель на текущий элемент списка
  38. };
  39.  
  40. // ####################################### Реализация #######################################
  41.  
  42. // конструктор по умолчанию
  43. template<typename Type>
  44. CyclicDoubleList<Type>::CyclicDoubleList()
  45. {
  46.     head = nullptr;
  47. }
  48.  
  49. // деструктор
  50. template<typename Type>
  51. inline CyclicDoubleList<Type>::~CyclicDoubleList()
  52. {
  53.     if (this->IsEmpty())
  54.         return;
  55.     this->Clear();
  56. }
  57.  
  58. // печать списка
  59. template<typename Type>
  60. void CyclicDoubleList<Type>::Print(System::Windows::Forms::ListBox^ listBoxForPrint)
  61. {
  62.     listBoxForPrint->ClearSelected();
  63.     listBoxForPrint->Items->Clear();
  64.     for (int i = 0; i != size; ++i)
  65.         listBoxForPrint->Items->Add(this->At(i));
  66. }
  67.  
  68. // вставка в начало
  69. template<typename Type>
  70. inline void CyclicDoubleList<Type>::InsertToBegin(Type value)
  71. {
  72.     if (this->IsEmpty())
  73.         this->CreateFirst(value);
  74.     else
  75.     {
  76.         Node<Type>^ tmp = gcnew Node<Type>;
  77.         tmp->data = value;
  78.         tmp->next = head;
  79.         tmp->prev = head->prev;
  80.         tmp->prev->next = tmp;
  81.         head->prev = tmp;
  82.         head = tmp;
  83.  
  84.         this->size++;
  85.     }
  86. }
  87.  
  88. // вставка после элемента с указанным индексом
  89. template<typename Type>
  90. inline void CyclicDoubleList<Type>::Insert(Type value, int index)
  91. {
  92.     if (this->IsEmpty())
  93.         throw gcnew System::Exception("List is empty");
  94.     if (index >= size)
  95.         throw gcnew System::IndexOutOfRangeException("Can not insert element");
  96.  
  97.     current = head;
  98.     for (int i = 0; i != index + 1; ++i)
  99.     {
  100.         if (i == index)
  101.         {
  102.             Node<Type>^ tmp = gcnew Node<Type>;
  103.             tmp->data = value;
  104.             tmp->next = current->next;
  105.             tmp->prev = current;
  106.             tmp->next->prev = tmp;
  107.             current->next = tmp;
  108.             this->size++;
  109.         }
  110.         current = current->next;
  111.     }
  112. }
  113.  
  114. // удаление элемента с указанным индексом
  115. template<typename Type>
  116. inline void CyclicDoubleList<Type>::Delete(int index)
  117. {
  118.     if (this->IsEmpty())
  119.         throw gcnew System::Exception("List is empty");
  120.     if (index >= size)
  121.         throw gcnew System::IndexOutOfRangeException("Can not delete list element");
  122.  
  123.     current = head;
  124.     if (index == 0 && size == 1)
  125.         this->Clear();
  126.     else if (index == 0)
  127.     {
  128.         current = head;
  129.         head->next->prev = head->prev;
  130.         head->prev->next = head->next;
  131.         head = current->next;
  132.  
  133.         delete current;
  134.         --size;
  135.     }
  136.     else if (index < size)
  137.     {
  138.         current = head->next;
  139.         for (int i = 1; i != index; ++i)
  140.             current = current->next;
  141.         current->prev->next = current->next;
  142.         current->next->prev = current->prev;
  143.         delete current;
  144.         --size;
  145.     }
  146. }
  147.  
  148. // удаление всего списка
  149. template<typename Type>
  150. inline void CyclicDoubleList<Type>::Clear()
  151. {
  152.     if (this->IsEmpty())
  153.         return;
  154.     if (size == 1)
  155.     {
  156.         delete head;
  157.         head = nullptr;
  158.         size = 0;
  159.         return;
  160.     }
  161.     int n = size;
  162.     size = 0;
  163.  
  164.     for (int i = 1; i != n; ++i)
  165.         this->Delete(i);
  166.     this->Delete(0);
  167.  
  168.     head = nullptr;
  169. }
  170.  
  171. // поиск элемента
  172. template<typename Type>
  173. inline int CyclicDoubleList<Type>::Find(Type dataToFind)
  174. {
  175.     if (this->IsEmpty())
  176.         throw gcnew System::Exception("List is empty");
  177.  
  178.     if (head->data == dataToFind)
  179.         return 0;
  180.  
  181.     current = head->next;
  182.     int index = 1;
  183.     while (current != head)
  184.     {
  185.         if (current->data == dataToFind)
  186.             return index;
  187.         ++index;
  188.         current = current->next;
  189.     }
  190.  
  191.     return -1;
  192. }
  193.  
  194. // возвращает элемент с указанным индексом
  195. template<typename Type>
  196. inline Type CyclicDoubleList<Type>::At(int index)
  197. {
  198.     if (this->IsEmpty())
  199.         throw gcnew System::Exception("List is empty");
  200.     if (index >= size)
  201.         throw gcnew System::IndexOutOfRangeException("Can not get list element");
  202.  
  203.     if (index == 0)
  204.         return head->data;
  205.     else if (index == size - 1)
  206.         return head->prev->data;
  207.     else
  208.     {
  209.         current = head->next;
  210.         for (int i = 1; i != index + 1; ++i)
  211.         {
  212.             if (i == index)
  213.                 return current->data;
  214.             current = current->next;
  215.         }
  216.     }
  217. }
  218.  
  219. // проверка списка на пустоту
  220. template<typename Type>
  221. inline bool CyclicDoubleList<Type>::IsEmpty()
  222. {
  223.     if (head == nullptr)
  224.         return true;
  225.     return false;
  226. }
  227.  
  228. // возвращает размер списка
  229. template<typename Type>
  230. inline int CyclicDoubleList<Type>::Size()
  231. {
  232.     return this->size;
  233. }
  234.  
  235. // создать первый элемент списка
  236. template<typename Type>
  237. inline void CyclicDoubleList<Type>::CreateFirst(Type value)
  238. {
  239.     this->head = gcnew Node<Type>;
  240.     this->head->data = value;
  241.     this->head->next = head;
  242.     this->head->prev = head;
  243.     this->size++;
  244. }
  245.  
RAW Paste Data