Advertisement
Guest User

Untitled

a guest
Nov 17th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.12 KB | None | 0 0
  1. #ifndef CONTAINERS_H_
  2. #define CONTAINERS_H_
  3.  
  4. #include <utility>
  5. #include <vector>
  6. #include <cassert>
  7.  
  8. namespace containers {
  9.  
  10. // --------------------------------------------------------------------------
  11.  
  12. template <typename T>
  13. class BiDirectionalList {
  14.  public:
  15.   struct Node{
  16.     T value;
  17.    private:
  18.     Node* pvl = nullptr;
  19.     Node* nvl = nullptr;
  20.    
  21.     Node(Node*, const T&, bool);
  22.     explicit Node(const T* val) : value(val) {}
  23.     Node(const Node&);
  24.     explicit Node(T val) : value(val) {}
  25.     friend class BiDirectionalList;
  26.   };
  27.  
  28.   BiDirectionalList() = default;
  29.   BiDirectionalList(const std::initializer_list<T>&);
  30.  
  31.   int Size() const;
  32.   bool IsEmpty() const;
  33.  
  34.   void PushFront(const T& value);
  35.   void PushBack(const T& value);
  36.  
  37.   Node* Front();
  38.   Node* Back();
  39.  
  40.   const Node* Front() const;
  41.   const Node* Back() const;
  42.  
  43.   void PopFront();
  44.   void PopBack();
  45.  
  46.   std::vector<T> ToVector() const;
  47.  
  48.   int Find(const T& value) const;
  49.   std::vector<int> FindAll(const T& value) const;
  50.  
  51.   Node* operator[](int);
  52.   const Node* operator[](int) const;
  53.  
  54.   void InsertBefore(Node* element, const T& value);
  55.   void InsertAfter(Node* element, const T& value);
  56.  
  57.   void Erase(Node* element);
  58.  
  59.   bool operator==(const BiDirectionalList<T>&) const;
  60.   bool operator!=(const BiDirectionalList<T>&) const;
  61.  
  62.   BiDirectionalList(const BiDirectionalList<T>&);
  63.   BiDirectionalList& operator=(const BiDirectionalList<T>&);
  64.  
  65.   BiDirectionalList(BiDirectionalList<T>&&);
  66.   BiDirectionalList& operator=(BiDirectionalList<T>&&);
  67.  
  68.   ~BiDirectionalList();
  69.  
  70.  protected:
  71.   int size_ = 0;
  72.   Node* first_ = nullptr;
  73.   Node* last_ = nullptr;
  74. };
  75. template<typename T>
  76. BiDirectionalList<T>::Node::Node(
  77.     BiDirectionalList<T>::Node* el,
  78.     const T& val,
  79.     bool flag) : value(val) {
  80.   if (flag) {
  81.     nvl = el->nvl;
  82.     pvl = el;
  83.     if (el->nvl != nullptr)
  84.       el->nvl->pvl = this;  //  -Требует дорабодки, как и многое другое
  85.     el->nvl = this;
  86.   } else {
  87.     nvl = el;
  88.     pvl = el->pvl;
  89.     if (el->pvl != nullptr)
  90.       el->pvl->nvl = this;
  91.     el->pvl = this;
  92.   }
  93. }
  94.  
  95. template<typename T>
  96. BiDirectionalList<T>::Node::Node(
  97.     const BiDirectionalList<T>::Node& n) : value(n.value),
  98.     nvl(n.nvl), pvl(n.pvl) {
  99. }
  100.  
  101. template<typename T>
  102. BiDirectionalList<T>::BiDirectionalList(const std::initializer_list<T>& list) {
  103.   if (list.size() == 0) {
  104.     first_ = nullptr;
  105.     last_ = nullptr;
  106.     size_ = 0;
  107.     return;
  108.   }
  109.   first_ = new Node(*list.begin());
  110.   size_ = list.size();
  111.   Node* prev = first_;
  112.   auto beg = list.begin();
  113.   beg++;
  114.   for (auto i = beg; i != list.end(); i++) {
  115.     prev = new Node(prev, *i, true);
  116.   }
  117.   last_ = prev;
  118. }
  119.  
  120. template<typename T>
  121. BiDirectionalList<T>::~BiDirectionalList() {
  122.   Node* next = last_;
  123.   first_ = nullptr;
  124.   last_ = nullptr;
  125.   while (next != nullptr) {
  126.     Node* now = next;
  127.     next = next->pvl;
  128.     now->pvl = nullptr;
  129.     now->nvl = nullptr;
  130.     delete now;
  131.   }
  132. }
  133.  
  134. template<typename T>
  135. int BiDirectionalList<T>::Size() const {
  136.   return size_;
  137. }
  138.  
  139. template<typename T>
  140. bool BiDirectionalList<T>::IsEmpty() const {
  141.   return size_ == 0;
  142. }
  143.  
  144. template<typename T>
  145. void BiDirectionalList<T>::PushFront(const T& value) {
  146.   size_++;
  147.   if (size_ == 1) {
  148.     first_ = new Node(value);
  149.     last_ = first_;
  150.     return;
  151.   }
  152.   first_ = new Node(first_, value, false);
  153. }
  154.  
  155. template<typename T>
  156. void BiDirectionalList<T>::PushBack(const T& value) {
  157.   size_++;
  158.   if (size_ == 1) {
  159.     first_ = new Node(value);
  160.     last_ = first_;
  161.     return;
  162.   }
  163.   last_ = new Node(last_, value, true);
  164. }
  165. template<typename T>
  166. typename BiDirectionalList<T>::Node*
  167. BiDirectionalList<T>::Front() {
  168.   return first_;
  169. }
  170. template<typename T>
  171. typename BiDirectionalList<T>::Node*
  172. BiDirectionalList<T>::Back() {
  173.   return last_;
  174. }
  175. template<typename T>
  176. void BiDirectionalList<T>::PopFront() {
  177.   if (size_ > 1) {
  178.     Node* buf = first_;
  179.     first_ = buf->nvl;
  180.     first_->pvl = nullptr;
  181.     delete buf;
  182.     size_ -= 1;
  183.     return;
  184.   }
  185.   if (size_ == 1) {
  186.     Node* buf = first_;
  187.     delete buf;
  188.     first_ = nullptr;
  189.     last_ = nullptr;
  190.     size_ = 0;
  191.   }
  192. }
  193.  
  194. template<typename T>
  195. void BiDirectionalList<T>::PopBack() {
  196.   if (size_ > 1) {
  197.     Node* buf = last_;
  198.     last_ = buf->pvl;
  199.     last_->nvl = nullptr;
  200.     delete buf;
  201.     size_ -= 1;
  202.     return;
  203.   }
  204.   if (size_ == 1) {
  205.     Node* buf = first_;
  206.     delete buf;
  207.     first_ = nullptr;
  208.     last_ = nullptr;
  209.     size_ = 0;
  210.   }
  211. }
  212.  
  213. template<typename T>
  214. std::vector<T> BiDirectionalList<T>::ToVector() const {
  215.   std::vector<T> ans;
  216.   Node* el = first_;
  217.   while (el != nullptr) {
  218.     ans.push_back(el->value);
  219.     el = el->nvl;
  220.   }
  221.   return ans;
  222. }
  223.  
  224. template<typename T>
  225. int BiDirectionalList<T>::Find(const T& value) const {
  226.   int ans = 0;
  227.   Node* el = first_;
  228.   while (el != nullptr) {
  229.     if (el->value == value) {
  230.       return ans;
  231.     }
  232.     el = el->nvl;
  233.     ans += 1;
  234.   }
  235.   return -1;
  236. }
  237.  
  238. template<typename T>
  239. std::vector<int> BiDirectionalList<T>::FindAll(
  240.     const T& value) const {
  241.   std::vector<int> ans;
  242.   int i = 0;
  243.   Node* el = first_;
  244.   while (el != nullptr) {
  245.     if (el->value == value) {
  246.       ans.push_back(i);
  247.     }
  248.     i++;
  249.     el = el->nvl;
  250.   }
  251.   return ans;
  252. }
  253. template<typename T>
  254. typename BiDirectionalList<T>::Node*
  255. BiDirectionalList<T>::operator[](int x) {
  256.   Node* ans = first_;
  257.   if (x > size_) {
  258.     return nullptr;
  259.   }
  260.   if (x == 0) {
  261.     return first_;
  262.   }
  263.   for (int i = 0; i < x; i++) {
  264.     ans = ans->nvl;
  265.   }
  266.   return ans;
  267. }
  268. template<typename T>
  269. void BiDirectionalList<T>::InsertBefore(
  270.     BiDirectionalList<T>::Node* element,
  271.     const T& value) {
  272.   size_++;
  273.   if (element == first_) {
  274.     PushFront(value);
  275.     return;
  276.   }
  277.   new Node(element, value, false);
  278. }
  279. template<typename T>
  280. void BiDirectionalList<T>::InsertAfter(
  281.     BiDirectionalList<T>::Node* element,
  282.     const T& value) {
  283.   size_++;
  284.   if (element == last_) {
  285.     PushBack(value);
  286.     return;
  287.   }
  288.   new Node(element, value, true);
  289. }
  290. template<typename T>
  291. void BiDirectionalList<T>::Erase(
  292.     BiDirectionalList<T>::Node* element) {
  293.   if (element == first_) {
  294.     PopFront();
  295.     return;
  296.   }
  297.   if (element == last_) {
  298.     PopBack();
  299.     return;
  300.   }
  301.   element->nvl->pvl = element->pvl;
  302.   element->pvl->nvl = element->nvl;
  303.   size_--;
  304.   delete element;
  305. }
  306. template<typename T>
  307. const typename BiDirectionalList<T>::Node*
  308. BiDirectionalList<T>::operator[](int x) const {
  309.   Node* ans = first_;
  310.   if (x > size_) {
  311.     return nullptr;
  312.   }
  313.   for (int i = 0; i < x; i++) {
  314.     ans = ans->nvl;
  315.   }
  316.   const Node* answer(ans);
  317.   return answer;
  318. }
  319. template<typename T>
  320. const typename BiDirectionalList<T>::Node*
  321. BiDirectionalList<T>::Front() const {
  322.   const Node* ans(first_);
  323.   return ans;
  324. }
  325.  
  326. template<typename T>
  327. const typename BiDirectionalList<T>::Node*
  328. BiDirectionalList<T>::Back() const {
  329.   const Node* ans(last_);
  330.   return ans;
  331. }
  332. template<typename T>
  333. bool BiDirectionalList<T>::operator==(
  334.     const BiDirectionalList<T>& list) const {
  335.   if (size_ != list.size_) {
  336.     return false;
  337.   }
  338.   Node* el1 = first_;
  339.   Node* el2 = list.first_;
  340.   while (el1 != nullptr) {
  341.     if (el1->value != el2->value) {
  342.       return false;
  343.     }
  344.     el1 = el1->nvl;
  345.     el2 = el2->nvl;
  346.   }
  347.   return true;
  348. }
  349. template<typename T>
  350. bool BiDirectionalList<T>::operator!=(
  351.     const BiDirectionalList<T>& list) const {
  352.   return !(*this == list);
  353. }
  354. template<typename T>
  355. BiDirectionalList<T>::BiDirectionalList(
  356.     const BiDirectionalList<T>& list) : size_(list.size_) {
  357.   if (list.size_ == 0) {
  358.     first_ = nullptr;
  359.     last_ = nullptr;
  360.     return;
  361.   }
  362.   Node* elem = list.first_;
  363.   first_ = new Node(*list.first_);
  364.   Node* coper = first_;
  365.   while (elem != nullptr) {
  366.     coper = new Node(coper, *elem, true);
  367.     elem = elem->nvl;
  368.   }
  369.   last_ = coper;
  370. }
  371. template<typename T>
  372. BiDirectionalList<T>& BiDirectionalList<T>::operator=(
  373.     const BiDirectionalList<T>& list) {
  374.   if (this == &list) {
  375.     return *this;
  376.   }
  377.   // Удалям то, что было раньше
  378.   Node* next = first_;
  379.   Node* now = nullptr;
  380.   while (next != nullptr) {
  381.     now = next;
  382.     next = now->nvl;
  383.     delete now;
  384.   }
  385.   // Пишем в массив новые значения
  386.   size_ = list.size_;
  387.   if (size_ == 0) {
  388.     first_ = nullptr;
  389.     last_ = nullptr;
  390.   }
  391.   Node* elem = list.first_;
  392.   first_ = new Node(*list.first_);
  393.   Node* coper = first_;
  394.   while (elem != nullptr) {
  395.     coper = new Node(coper, *elem, true);
  396.     elem = elem->nvl;
  397.   }
  398.   last_ = coper;
  399.   return *this;
  400. }
  401. template<typename T>
  402. BiDirectionalList<T>::BiDirectionalList(
  403.     BiDirectionalList<T>&& list) : size_(list.size_),
  404.                                    first_(list.first_),
  405.                                    last_(list.last_) {
  406.   list.last_ = nullptr;
  407.   list.first_ = nullptr;
  408. }
  409. template<typename T>
  410. BiDirectionalList<T>& BiDirectionalList<T>::operator=(
  411.     BiDirectionalList<T>&& list) {
  412.   if (this = &list) {
  413.     return *this;
  414.   }
  415.   // Удалям то, что было раньше
  416.   Node* next = first_;
  417.   Node* now = nullptr;
  418.   while (next != nullptr) {
  419.     now = next;
  420.     next = now->nvl;
  421.     delete now;
  422.   }
  423.   // Копируем все в массив
  424.   size_ = list.size_;
  425.   first_ = list.size_;
  426.   last_ - list.size_;
  427.   list.last_ = nullptr;
  428.   list.first_ = nullptr;
  429.  
  430.   return *this;
  431. }
  432. // --------------------------------------------------------------------------
  433.  
  434. // Тут следует расположить код решения задачи 2 (Queue / Stack).
  435. template <typename T>
  436. class Queue {
  437.  public:
  438.     Queue() = default;
  439.     Queue(const std::initializer_list<T>&);
  440.     void Push(const T&);
  441.     void Pop();
  442.     T& Get();
  443.     int Size();
  444.     bool IsEmpty();
  445.     bool operator==(const Queue<T>&);
  446.     bool operator!=(const Queue<T>&);
  447.  private:
  448.     BiDirectionalList<T> mas;
  449. };
  450. template<typename T>
  451. void Queue<T>::Push(const T& x) {
  452.   mas.PushBack(x);
  453. }
  454. template<typename T>
  455. void Queue<T>::Pop() {
  456.   mas.PopFront();
  457. }
  458. template<typename T>
  459. T& Queue<T>::Get() {
  460.   return mas.Front()->value;
  461. }
  462. template<typename T>
  463. int Queue<T>::Size() {
  464.   return mas.Size();
  465. }
  466. template<typename T>
  467. bool Queue<T>::IsEmpty() {
  468.   return mas.IsEmpty();
  469. }
  470. template<typename T>
  471. bool Queue<T>::operator==(const Queue<T>& obj) {
  472.   return mas == obj.mas;
  473. }
  474. template<typename T>
  475. bool Queue<T>::operator!=(const Queue<T>& obj) {
  476.   return mas != obj.mas;
  477. }
  478. template<typename T>
  479. Queue<T>::Queue(const std::initializer_list<T>& list) : mas(list) {
  480. }
  481.  
  482. // --------------------------------------------------------------------------
  483.  
  484. // Раскоментируйте нужные строки ниже для выбора варианта
  485.  
  486. enum class Variant {
  487.   kQueue,
  488.   kStack,
  489. };
  490.  
  491. Variant GetVariant() {
  492.   return Variant::kQueue;
  493.   // return Variant::kStack;
  494. }
  495.  
  496. template<typename T>
  497. using Container = Queue<T>;
  498.  
  499. // template<typename T>
  500. // using Container = Stack<T>;
  501.  
  502. // --------------------------------------------------------------------------
  503.  
  504. }  // namespace containers
  505.  
  506. #endif  // CONTAINERS_H_
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement