Advertisement
jeanleopoldo

DoublyLinkedList

Apr 28th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.07 KB | None | 0 0
  1. //  Copyright [2017] <Jean Leopoldo>
  2. #ifndef STRUCTURES_DOUBLY_LINKED_LIST_H
  3. #define STRUCTURES_DOUBLY_LINKED_LIST_H
  4.  
  5. #include <cstdint>
  6. #include <stdexcept>
  7.  
  8. namespace structures {
  9.  
  10. template<typename T>
  11. //! class DoublyLinkedList
  12. /*
  13. *  class DoublyLinkedList
  14. */
  15. class DoublyLinkedList {
  16.  public:
  17. //! constructor DoublyLinkedList
  18. /*
  19. *  constructor DoublyLinkedList
  20. */
  21.     DoublyLinkedList() {
  22.         head = nullptr;
  23.         size_ = 0;
  24.     }
  25. //! constructor DoublyLinkedList
  26. /*
  27. *  constructor DoublyLinkedList
  28. */
  29.     ~DoublyLinkedList() {
  30.         clear();
  31.     }
  32. //! constructor DoublyLinkedList
  33. /*
  34. *  constructor DoublyLinkedList
  35. */
  36.     void clear() {
  37.         Node *aux;
  38.         while (!empty()) {
  39.             aux = head;
  40.             head = head->next();
  41.             delete aux;
  42.         }
  43.     }
  44. //! pop_back DoublyLinkedList
  45. /*
  46. *  checks if list is empty
  47. */
  48.     void push_back(const T& data) {
  49.         Node *node = new Node(data);
  50.         if (node == nullptr)
  51.             throw std::out_of_range("full");
  52.         size_++;
  53.         Node *aux = head;
  54.         for (int i = 0; i < size_-1; i++)
  55.             aux = aux->next();
  56.         node->prev(aux);
  57.         aux->next(node);
  58.         delete aux;
  59.     }
  60. //! pop_back DoublyLinkedList
  61. /*
  62. *  insert data at the front of the list
  63. */
  64.     void push_front(const T& data) {
  65.         Node *node = new Node(data, head);
  66.         if (node == nullptr)
  67.             throw std::out_of_range("full");
  68.         size_++;
  69.         head->prev(node);
  70.         head = node;
  71.     }
  72. //! pop_back DoublyLinkedList
  73. /*
  74. *  insert data at a specified index on the list
  75. */
  76.     void insert(const T& data, std::size_t index) {
  77.         Node *node = new Node(data);
  78.         if (node == nullptr)
  79.             throw std::out_of_range("full");
  80.         if (index == 1)
  81.             push_front(data);
  82.         size_++;
  83.         Node *aux = head;
  84.         for (int i = 0; i < index-1; i++)
  85.             aux = aux->next();
  86.         node->next(aux->next());
  87.         node->prev(aux);
  88.         aux->next(node);
  89.         node->next()->prev(node);
  90.         delete aux;
  91.     }
  92. //! pop_back DoublyLinkedList
  93. /*
  94. *  checks if list is empty
  95. */
  96.     void insert_sorted(const T& data) {
  97.         Node *node = new Node(data, head);
  98.         if (node == nullptr)
  99.             throw std::out_of_range("full");
  100.         Node *aux = head;
  101.         for (int i = 0; i < size_-1; i++)
  102.             if (data < aux->data())
  103.                 insert(data, i);
  104.             aux = aux->next();
  105.         delete aux;
  106.     }
  107. //! pop_back DoublyLinkedList
  108. /*
  109. *  checks if list is empty
  110. */
  111.     T pop(std::size_t index) {
  112.         if (empty())
  113.             throw std::out_of_range("empty");
  114.         if (indexOut(index))
  115.             throw std::out_of_range("invalid index");
  116.         size_--;
  117.         Node *aux = head;
  118.         Node *del;
  119.         T data;
  120.         for (int i = 0; i < index-1; i++)
  121.             aux = aux->next();
  122.         del = aux->next();
  123.         data = del->data();
  124.         aux->next(del->next());
  125.         del->next()->prev(aux);
  126.         delete aux;
  127.         delete del;
  128.         return data;
  129.     }
  130. //! pop_back DoublyLinkedList
  131. /*
  132. *  checks if list is empty
  133. */
  134.     T pop_back() {
  135.         return pop(size_);
  136.     }
  137. //! pop_front DoublyLinkedList
  138. /*
  139. *  checks if list is empty
  140. */
  141.     T pop_front() {
  142.         if (empty())
  143.             throw std::out_of_range("empty");
  144.         size_--;
  145.         T data = head->data();
  146.         head = head->next();
  147.         return data;
  148.     }
  149. //! empty DoublyLinkedList
  150. /*
  151. *  checks if list is empty
  152. */
  153.     void remove(const T& data) {
  154.         if (empty())
  155.             throw std::out_of_range("empty");
  156.         Node *aux = head;
  157.         for (int i = 0; i < size_-1; i++)
  158.             if (aux->data() == data)
  159.                 pop(i);
  160.         delete aux;
  161.         throw std::out_of_range("data not found");
  162.     }
  163. //! empty DoublyLinkedList
  164. /*
  165. *  checks if list is empty
  166. */
  167.     bool empty() const {
  168.         if (size_ == 0)
  169.             return true;
  170.         return false;
  171.     }
  172. //! contains DoublyLinkedList
  173. /*
  174. *  checks if data exists in the list
  175. */
  176.     bool contains(const T& data) const {
  177.         if (empty())
  178.             throw std::out_of_range("empty");
  179.         Node *aux = head;
  180.         for (int i = 0; i < size_-1; i++)
  181.             if (aux->data() == data)
  182.                 return true;
  183.             aux = aux->next();
  184.         return false;
  185.     }
  186. //! at DoublyLinkedList
  187. /*
  188. *  returns data from the index
  189. */
  190.     T& at(std::size_t index) {
  191.         if (indexOut(index))
  192.             throw std::out_of_range("invalid index");
  193.         if (empty())
  194.             throw std::out_of_range("empty");
  195.         Node *aux = head;
  196.         for (int i = 0; i < index-1; i++)
  197.             aux = aux->next();
  198.         return aux->data();
  199.     }
  200. //! at DoublyLinkedList
  201. /*
  202. *  returns data from the index
  203. */
  204.     const T& at(std::size_t index) const {
  205.         if (indexOut(index))
  206.             throw std::out_of_range("invalid index");
  207.         if (empty())
  208.             throw std::out_of_range("empty");
  209.         Node *aux = head;
  210.         T data;
  211.         for (int i = 0; i < index-1; i++)
  212.             aux = aux->next();
  213.         data = aux->data();
  214.         delete aux;
  215.         return data;
  216.     }
  217. //! find DoublyLinkedList
  218. /*
  219. *  returns the position where data is
  220. */
  221.     std::size_t find(const T& data) const {
  222.         if (empty())
  223.             throw std::out_of_range("empty");
  224.         Node *aux = head;
  225.         for (int i = 0; i < size_-1; i++)
  226.             if (aux->data() == data)
  227.                 return i;
  228.             aux = aux->next();
  229.         throw std::out_of_range("data not found");
  230.     }
  231. //! size DoublyLinkedList
  232. /*
  233. *  returns size of the list
  234. */
  235.     std::size_t size() const {
  236.         return size_;
  237.     }
  238.  
  239.  private:
  240.     class Node {
  241.      public:
  242.         explicit Node(const T& data) {
  243.             data_ = data;
  244.             next_ = nullptr;
  245.             prev_ = nullptr;
  246.         }
  247.         Node(const T& data, Node* next) {
  248.             data_ = data;
  249.             next_ = next;
  250.             prev_ = nullptr;
  251.         }
  252.         Node(const T& data, Node* prev, Node* next) {
  253.             data_ = data;
  254.             next_ = next;
  255.             prev_ = prev;
  256.         }
  257.  
  258.         T& data() {
  259.             return data_;
  260.         }
  261.         const T& data() const {
  262.             return data_;
  263.         }
  264.  
  265.         Node* prev() {
  266.             return prev_;
  267.         }
  268.         const Node* prev() const {
  269.             return prev_;
  270.         }
  271.  
  272.         void prev(Node* node) {
  273.             prev_ = node;
  274.         }
  275.  
  276.         Node* next() {
  277.             return next_;
  278.         }
  279.         const Node* next() const {
  280.             return next_;
  281.         }
  282.  
  283.         void next(Node* node) {
  284.             next_ = node;
  285.         }
  286.  
  287.      private:
  288.         T data_;
  289.         Node* prev_;
  290.         Node* next_;
  291.     };
  292.  
  293.     Node* head;
  294.     std::size_t size_;
  295.  
  296.     bool indexOut(std::size_t index) {
  297.         if (index < 1 || index > size_)
  298.             return true;
  299.         return false;
  300.     }
  301. };
  302.  
  303. }  //  namespace structures
  304.  
  305. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement