Advertisement
jeanleopoldo

DoublyCircularList

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