Advertisement
Guest User

Doubly Linked List C++

a guest
Nov 21st, 2019
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.82 KB | None | 0 0
  1. #include "stdafx.h"
  2. /*
  3. Double linked list
  4. */
  5.  
  6.  
  7.  
  8. template <typename T>
  9. class List
  10. {
  11. public:
  12.  
  13.     int GetSize() { return Size; }
  14.  
  15.     void clear();
  16.     void push_front(T data);
  17.     void push_back(T data);
  18.     void pop_front();
  19.     void pop_back();
  20.    
  21.     void insert(T data, int index);
  22.     void removeAt(int index);
  23.  
  24.     T & operator [] (const int index);
  25.  
  26.     void PrintFromHead();
  27.     void PrintFromTail();
  28.  
  29.     List <T>();
  30.     ~List <T>();
  31.  
  32. private:
  33.  
  34.     template <typename T>
  35.     class Node
  36.     {
  37.     public:
  38.         Node (T data = T(), Node *pNext = nullptr, Node *pPrev = nullptr)
  39.         {
  40.             this->data = data;
  41.             this->pNext = pNext;
  42.             this->pPrev = pPrev;
  43.         }
  44.  
  45.         T data;
  46.         Node *pNext;
  47.         Node *pPrev;
  48.     };
  49.  
  50.     Node <T> *head;
  51.     Node <T> *tail;
  52.     int Size;
  53. };
  54.  
  55. template <typename T> List <T>::List()
  56. {
  57.     head = nullptr;
  58.     tail = nullptr;
  59.     Size = 0;
  60. }
  61.  
  62. template <typename T> List <T>::~List()
  63. {
  64.     clear();
  65. }
  66.  
  67. template<typename T>
  68. void List<T>::clear()
  69. {
  70.     while (Size)
  71.     {
  72.         pop_front();
  73.     }
  74. }
  75.  
  76. template <typename T>
  77. void List <T>::push_front(T data)
  78. {
  79.     if (Size > 1)
  80.     {
  81.         Node <T> *temp = head;
  82.         head = new Node <T>(data, head);
  83.         temp->pPrev = head;
  84.     }
  85.     else if (Size == 1)
  86.     {
  87.         head = new Node <T>(data, head);
  88.         tail->pPrev = this->head;
  89.     }
  90.     else
  91.     {
  92.         head = tail = new Node <T>(data, head, tail);
  93.     }
  94.     Size++;
  95. }
  96.  
  97. template <typename T>
  98. void List <T>::push_back(T data)
  99. {
  100.     if (Size > 1)
  101.     {
  102.         Node <T> *temp = tail;
  103.         tail = new Node <T>(data, nullptr, tail);
  104.         temp->pNext = tail;
  105.     }
  106.     else if (Size == 1)
  107.     {
  108.         tail = new Node <T>(data, nullptr, tail);
  109.         head->pNext = this->tail;
  110.     }
  111.     else
  112.     {
  113.         head = tail = new Node <T>(data, head, tail);
  114.     }
  115.     Size++;
  116. }
  117.  
  118. template <typename T>
  119. void List <T>::pop_front()
  120. {
  121.     if (Size > 1)
  122.     {
  123.         Node <T> *temp = head;
  124.         head = head->pNext;
  125.         delete temp;
  126.     }
  127.     else if (Size == 1)
  128.     {
  129.         Node <T> *temp = head;
  130.         tail = head = head->pNext;
  131.         delete temp;
  132.     }
  133.  
  134.     Size--;
  135. }
  136.  
  137. template <typename T>
  138. void List <T>::pop_back()
  139. {
  140.     if (Size > 1)
  141.     {
  142.         Node <T> *temp = tail;
  143.         tail = tail->pPrev;
  144.         delete temp;
  145.     }
  146.     else if (Size == 1)
  147.     {
  148.         Node <T> *temp = tail;
  149.         tail = head = tail->pPrev;
  150.         delete temp;
  151.     }
  152.  
  153.     Size--;
  154. }
  155.  
  156. template <typename T>
  157. void List <T>::insert(T data, int index)
  158. {
  159.     if (index == 0) push_front(data);
  160.  
  161.     else if (index == Size || index > Size) push_back(data);
  162.     /*здесь можно реализовать проверку, if(index > Size) то кидать исключение, с сообщением пользователю -
  163.     - что он хочет добавить узел по индексу, до которого список еще не дорос. Либо оставить данную реализацию,
  164.     в которой узел просто добавляется в конец*/
  165.  
  166.     else if (index <= Size / 2)
  167.     {
  168.         Node<T> *previous = this->head;
  169.         for (int i = 0; i < index - 1; i++)
  170.         {
  171.             previous = previous->pNext;
  172.         }
  173.  
  174.         Node<T> *newNode = new Node<T>(data, previous->pNext, previous);
  175.  
  176.         previous->pNext = newNode;
  177.         Node<T> *next = newNode->pNext;
  178.         next->pPrev = newNode;
  179.  
  180.         Size++;
  181.     }
  182.  
  183.     else if (index > Size / 2)
  184.     {
  185.         Node<T> *next = this->tail;
  186.         for (int i = Size - 1; index < i; i--)
  187.         {
  188.             next = next->pPrev;
  189.         }
  190.  
  191.         Node<T> *newNode = new Node<T>(data, next, next->pPrev);
  192.  
  193.         next->pPrev = newNode;
  194.         Node<T> *previous = newNode->pPrev;
  195.         previous->pNext = newNode;
  196.  
  197.         Size++;
  198.     }
  199. }
  200.  
  201. template <typename T>
  202. void List <T>::removeAt(int index)
  203. {
  204.     if (index == 0) pop_front();
  205.  
  206.     else if (index == Size || index > Size) pop_back();
  207.     /*здесь можно реализовать проверку, if(index > Size) то кидать исключение, с сообщением пользователю -
  208.     - что он хочет удалить узел по индексу, которого не существует. Либо оставить данную реализацию,
  209.     в которой просто удаляется последний узел*/
  210.  
  211.     else if (index <= Size / 2)
  212.     {
  213.         Node<T> *previous = this->head;
  214.         for (int i = 0; i < index - 1; i++)
  215.         {
  216.             previous = previous->pNext;
  217.         }
  218.  
  219.         Node<T> *toDelete = previous->pNext;
  220.         previous->pNext = toDelete->pNext;
  221.         Node<T> *next = toDelete->pNext;
  222.         delete toDelete;
  223.         next->pPrev = previous;
  224.  
  225.         Size--;
  226.     }
  227.  
  228.     else if (index > Size / 2)
  229.     {
  230.         Node<T> *next = this->tail;
  231.         for (int i = Size - 1; index < i; i--)
  232.         {
  233.             next = next->pPrev;
  234.         }
  235.  
  236.         Node<T> *toDelete = next->pPrev;
  237.         next->pPrev = toDelete->pPrev;
  238.         Node<T> *previous = toDelete->pPrev;
  239.         delete toDelete;
  240.         previous->pNext = next;
  241.  
  242.         Size--;
  243.     }
  244. }
  245.  
  246. template <typename T>
  247. T & List <T>::operator[] (const int index)
  248. {
  249.     if (index <= Size / 2)
  250.     {
  251.         int counter = 0;
  252.         Node <T> *current = this->head;
  253.  
  254.         while (current != nullptr)
  255.         {
  256.             if (counter == index) return current->data;
  257.             current = pNext;
  258.             counter++;
  259.         }
  260.     }
  261.     else
  262.     {
  263.         int counter = Size - 1;
  264.         Node <T> *current = this->tail;
  265.  
  266.         while (current != nullptr)
  267.         {
  268.             if (counter == index) return current->data;
  269.             current = pPrev;
  270.             counter--;
  271.         }
  272.     }
  273. }
  274.  
  275. template <typename T>
  276. void List <T>::PrintFromHead()
  277. {
  278.     cout << "Come the method PrintFromHead:" << endl;
  279.     Node <T> *print = head;
  280.     while (print)
  281.     {
  282.         cout << print->data << endl;
  283.         print = print->pNext;
  284.     }
  285.     cout << endl;
  286. }
  287.  
  288. template <typename T>
  289. void List <T>::PrintFromTail()
  290. {
  291.     cout << "Come the method PrintFromTail:" << endl;
  292.     Node <T> *print = tail;
  293.     while (print)
  294.     {
  295.         cout << print->data << endl;
  296.         print = print->pPrev;
  297.     }
  298.     cout << endl;
  299. }
  300.  
  301. int main()
  302. {
  303.     List <int> lst;
  304.  
  305.  
  306.     lst.insert(1,0);
  307.     lst.insert(2,1);
  308.     lst.insert(4,3);
  309.     lst.insert(3,2);
  310.  
  311.     lst.PrintFromHead();
  312.     lst.PrintFromTail();
  313.  
  314.     lst.removeAt(3);
  315.  
  316.     lst.PrintFromHead();
  317.  
  318.     lst.removeAt(1);
  319.    
  320.    
  321.     return 0;
  322. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement