Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- template <typename ElemT>
- class List
- {
- class Node
- {
- public:
- ElemT data;
- Node* next;
- Node* prev;
- Node(const ElemT& dataP, Node* nextP = nullptr, Node* prevP = nullptr)
- :data{ dataP }, next{ nextP }, prev{ prevP } {};
- };
- Node* head;
- Node* tail;
- size_t size;
- Node* getNode(size_t idx);
- public:
- List() : head{ nullptr }, tail{ nullptr }, size{ 0 } {}
- List(const List& listP) : head{ nullptr }, tail{ nullptr }, size{ 0 }
- {
- for (List::Node* curr{ listP.head }; curr; curr = curr->next)
- {
- push_back(curr->data);
- }
- std::cout << "Copy-shmopy!\n";
- };
- List(List&& listP) : head{ listP.head }, tail{ listP.tail }, size{ listP.size }
- {
- listP.head = nullptr;
- listP.tail = nullptr;
- listP.size = 0;
- std::cout << "I liket to mov'it, mov'it! :[]\n";
- };
- List(const std::initializer_list<ElemT> initList) : head{ nullptr }, tail{ nullptr }, size{ 0 }
- {
- for (const auto& elem : initList)
- {
- push_back(elem);
- }
- };
- ElemT& front() { return head->data; };
- const ElemT& front()const { return head->data; };
- ElemT& back() { return tail->data; };
- const ElemT& back()const { return tail->data; };
- const size_t getSize() const { return size; };
- bool empty() const { return size == 0; };
- void push_back(const ElemT& data);
- void push_front(const ElemT& data);
- bool pop_back();
- bool pop_front();
- void clear();
- ElemT& operator[](size_t idx);
- void insertAt(size_t idx, const ElemT& data);
- void deleteAt(size_t idx);
- ~List();
- template <typename ElemT>
- friend std::ostream& operator<<(std::ostream& out, const List<ElemT>& list)
- {
- out << "[ ";
- for (List<ElemT>::Node* curr{ list.head }; curr; curr = curr->next)
- {
- out << curr->data << ' ';
- }
- out << "]";
- return out;
- };
- template <typename ElemT>
- friend List<ElemT> operator+(const List<ElemT>& lhs, const List<ElemT>& rhs)
- {
- List<ElemT> res;
- for (List::Node* curr{ lhs.head }; curr; curr = curr->next)
- {
- res.push_back(curr->data);
- }
- for (List::Node* curr{ rhs.head }; curr; curr = curr->next)
- {
- res.push_back(curr->data);
- }
- return res;
- };
- template <typename ElemT>
- friend List<ElemT> operator*(const List<ElemT>& lhs, const List<ElemT>& rhs)
- {
- List<ElemT> res;
- for (List::Node* currL{ lhs.head }; currL; currL = currL->next)
- {
- for (List::Node* currR{ rhs.head }; currR; currR = currR->next)
- {
- if (currL->data == currR->data)
- {
- res.push_back(currL->data);
- break;
- }
- }
- }
- for (List::Node* currR{ rhs.head }; currR; currR = currR->next)
- {
- for (List::Node* currL{ lhs.head }; currL; currL = currL->next)
- {
- if (currL->data == currR->data)
- {
- res.push_back(currL->data);
- break;
- }
- }
- }
- return res;
- };
- };
- template <typename ElemT>
- void List<ElemT>::push_back(const ElemT& data)
- {
- Node* tmp{ tail };
- tail = new Node{ data, nullptr, tail };
- if (tmp)
- {
- tmp->next = tail;
- }
- ++size;
- if (!head)
- {
- head = tail;
- }
- //if (!head)
- //{
- // head = new Node{ data };
- // tail = head;
- //}
- //else
- //{
- // tail->next = new Node{ data, nullptr, tail };
- // tail = tail->next;
- //}
- //++size;
- }
- template <typename ElemT>
- void List<ElemT>::push_front(const ElemT& data)
- {
- Node* tmp{ head };
- head = new Node{ data, head, nullptr };
- if (tmp)
- {
- tmp->prev = head;
- }
- ++size;
- if (!tail)
- {
- tail = head;
- }
- }
- template <typename ElemT>
- bool List<ElemT>::pop_front()
- {
- if (head)
- {
- if (tail == head)
- {
- delete tail;
- size = 0;
- tail = nullptr;
- head = nullptr;
- return true;
- }
- Node* tmp{ head };
- head = head->next;
- head->prev = nullptr;
- delete tmp;
- --size;
- return true;
- }
- return false;
- }
- template <typename ElemT>
- bool List<ElemT>::pop_back()
- {
- if (tail)
- {
- if (tail == head)
- {
- delete tail;
- size = 0;
- tail = nullptr;
- head = nullptr;
- return true;
- }
- Node* tmp{ tail };
- tail = tail->prev;
- tail->next = nullptr;
- delete tmp;
- --size;
- return true;
- }
- return false;
- }
- template <typename ElemT>
- void List<ElemT>::clear()
- {
- while (tail)
- {
- std::cout << "Clear for: " << back() << '\n';
- pop_back();
- }
- }
- template <typename ElemT>
- List<ElemT>::~List()
- {
- while (head)
- {
- pop_front();
- }
- }
- template<typename ElemT>
- typename List<ElemT>::Node* List<ElemT>::getNode(size_t idx)
- {
- Node* curr{ nullptr };
- int cnt;
- if (idx >= 0 and idx < size)
- {
- 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 ElemT>
- ElemT& List<ElemT>::operator [](size_t idx)
- {
- return getNode(idx)->data;
- };
- template<typename ElemT>
- void List<ElemT>::insertAt(size_t idx, const ElemT& 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 ElemT>
- void List<ElemT>::deleteAt(size_t idx)
- {
- Node* curr = getNode(idx);
- if (curr)
- {
- 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 = nullptr;
- tail = nullptr;
- size = 0;
- }
- delete curr;
- }
- }
- int main()
- {
- List<int> a;
- a.push_back(1);
- a.push_back(2);
- a.push_back(3);
- a.push_back(4);
- std::cout << "a -> " << a << '\n';
- List<int> b{a};
- std::cout << "b -> " << b << '\n';
- List<int> c;
- c.push_back(5);
- c.push_back(6);
- c.push_back(7);
- c.push_back(8);
- std::cout << "c -> " << c << '\n';
- List<int> d{ b + c };
- std::cout << "d -> " << d << '\n';
- List<int> e{ 1,3,5,7,3,5,7,1 };
- List<int> f{ 2,1,4,6,7,1,6,7 };
- std::cout << "e -> " << e << '\n';
- std::cout << "f -> " << f << '\n';
- List<int> g{ e * f };
- std::cout << "g -> " << g << '\n';
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement