Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- template <typename T>
- class List
- {
- class Node
- {
- public:
- T data;
- Node* next;
- Node* prev;
- Node(const T& data_, Node* next_ = nullptr, Node* prev_ = nullptr) : data{ data_ }, next{ next_ }, prev{ prev_ } {};
- };
- Node* head;
- Node* tail;
- size_t size;
- Node* getNode(size_t idx);
- public:
- List() : head{ nullptr }, tail{ nullptr }, size{ 0 } {};
- void push_back(const T& data);
- void push_front(const T& data);
- const size_t getSize()const { return size; };
- T& front() { return head->data; };
- T& back() { return tail->data; };
- void pop_front();
- void pop_back();
- void clear();
- T& operator[](size_t idx);
- void insertAt(size_t idx, const T& data);
- void deleteAt(size_t idx);
- ~List();
- };
- template<typename T>
- void List<T>::push_back(const T& data)
- {
- if (!head)
- {
- head = new Node{ data };
- tail = head;
- }
- else
- {
- tail->next = new Node{ data, nullptr, tail };
- tail = tail->next;
- }
- ++size;
- }
- template<typename T>
- void List<T>::push_front(const T& data)
- {
- Node* tmp{ head };
- head = new Node{ data, head, nullptr };
- if (tmp)
- {
- tmp->prev = head;
- }
- ++size;
- if (!tail)
- {
- tail = head;
- }
- }
- template<typename T>
- void List<T>::pop_front()
- {
- if (head)
- {
- Node* tmp = head;
- head = head->next;
- delete tmp;
- --size;
- }
- }
- template<typename T>
- void List<T>::pop_back()
- {
- if (tail)
- {
- Node* tmp = tail;
- tail = tail->prev;
- delete tmp;
- --size;
- }
- }
- template<typename T>
- void List<T>::clear()
- {
- while (tail)
- {
- std::cout << "Clear " << back() << '\n';
- pop_back();
- }
- head = nullptr;
- }
- template<typename T>
- T& List<T>::operator [](size_t idx)
- {
- return getNode(idx)->data;
- };
- template<typename T>
- typename List<T>::Node* List<T>::getNode(size_t idx)
- {
- Node* curr;
- size_t cnt;
- if (idx > (size / 2))
- {
- for(curr=tail, cnt=size-1; cnt>idx; curr=curr->prev, --cnt);
- }
- else
- {
- for(curr=head, cnt=0; cnt<idx; curr=curr->next, ++cnt);
- }
- return curr;
- }
- template<typename T>
- void List<T>::insertAt(size_t idx, const T &data)
- {
- Node* curr = getNode(idx);
- if (!curr or curr == tail ) { push_back(data); return;};
- Node* newNode = new Node{data, curr->next, curr};
- curr->next = newNode;
- newNode->next->prev = newNode;
- ++size;
- }
- template<typename T>
- void List<T>::deleteAt(size_t idx)
- {
- Node* curr = getNode(idx);
- if (curr->prev) {curr->prev->next = curr->next;} else { head = curr->next;}
- if (curr->next) {curr->next->prev = curr->prev;} else { tail = curr->prev;}
- --size;
- if (curr == head and curr == tail) {head = tail = nullptr; size = 0; }
- delete curr;
- }
- template<typename T>
- List<T>::~List()
- {
- while (head)
- {
- std::cout << "Destruct " << front() << '\n';
- pop_front();
- }
- }
- int main()
- {
- List<int> l;
- std::cout << "Size: " << l.getSize() << '\n';
- l.push_back(26);
- l.push_back(42);
- std::cout << "Size: " << l.getSize() << '\n';
- std::cout << "Front: " << l.front() << '\n';
- l.pop_front();
- std::cout << "Front: " << l.front() << '\n';
- l.pop_front();
- l.push_back(1);
- l.push_back(2);
- l.push_back(3);
- l.push_back(4);
- std::cout << "####" << '\n';
- std::cout << "Front: " << l.front() << '\n';
- std::cout << "Back: " << l.back() << '\n';
- std::cout << "####" << '\n';
- l.clear();
- std::cout << "Size: " << l.getSize() << '\n';
- l.push_back(1);
- l.push_back(2);
- l.push_back(3);
- l.push_back(4);
- std::cout << "####" << '\n';
- std::cout << "Front: " << l.front() << '\n';
- std::cout << "Back: " << l.back() << '\n';
- l.pop_back();
- std::cout << "Back: " << l.back() << '\n';
- std::cout << "####" << '\n';
- l.clear();
- std::cout << "Size: " << l.getSize() << '\n';
- l.push_front(22);
- l.push_front(23);
- l.push_front(24);
- std::cout << "####" << '\n';
- std::cout << "Front: " << l.front() << '\n';
- std::cout << "Back: " << l.back() << '\n';
- l.clear();
- for (int i{ 0 }; i < 10; ++i)
- {
- l.push_front(i);
- }
- std::cout << "Size: " << l.getSize() << '\n';
- std::cout << "[][][][][][]\n";
- for (int i{ 0 }; i < l.getSize(); ++i)
- {
- std::cout << l[i] << '\n';
- }
- std::cout << "[][][][][][]\n";
- l.clear();
- l.push_back(333);
- std::cout << "Front: " << l.front() << '\n';
- l.deleteAt(0);
- l.push_front(444);
- std::cout << "Back: " << l.back() << '\n';
- l.deleteAt(0);
- for (int i{ 0 }; i < 10; ++i)
- {
- l.push_front(i);
- }
- l.deleteAt(9);
- l.deleteAt(5);
- l.deleteAt(0);
- std::cout << "Size: " << l.getSize() << '\n';
- std::cout << "[][][][][][]\n";
- for (int i{ 0 }; i < l.getSize(); ++i)
- {
- std::cout << l[i] << '\n';
- }
- std::cout << "[][][][][][]\n";
- l.clear();
- l.insertAt(0, 1);
- l.insertAt(0, 2);
- l.insertAt(0, 3);
- l.insertAt(0, 4);
- l.insertAt(0, 5);
- l.insertAt(2, 333);
- l.deleteAt(3);
- l.insertAt(4, 444);
- std::cout << "Front: " << l.front() << '\n';
- std::cout << "Back: " << l.back() << '\n';
- return 0;
- }
Add Comment
Please, Sign In to add comment