#ifndef DOUBLY_LINKED_LIST #define DOUBLY_LINKED_LIST template class DLLNode { public: DLLNode() { next = prev = nullptr; } DLLNode(const T& el, DLLNode *n = nullptr, DLLNode *p = nullptr) { info = el; next = n; prev = p; } T info; DLLNode *next, *prev; }; template class DoublyLinkedList { public: DoublyLinkedList() { head = tail = nullptr; } void addToDLLTail(const T&); T deleteFromDLLTail(); ~DoublyLinkedList() { clear(); } bool isEmpty() const { return head == nullptr; } void clear(); void setToNull() { head = tail = nullptr; } void addInMiddle(const T&); void addToDLLHead(const T&); T deleteFromDLLHead(); T& firstEl(); T* find(const T&) const; protected: DLLNode *head, *tail; friend ostream& operator<<(ostream&, const DoublyLinkedList&); }; template void DoublyLinkedList::addToDLLHead(const T& el) { if (head != nullptr) { head = new DLLNode(el,head,nullptr); head->next->prev = head; } else head = tail = new DLLNode(el); } template void DoublyLinkedList::addToDLLTail(const T& el) { if (tail != nullptr) { tail = new DLLNode(el,nullptr,tail); tail->prev->next = tail; } else head = tail = new DLLNode(el); } template T DoublyLinkedList::deleteFromDLLHead() { T el = head->info; if (head == tail) { // if only one DLLNode on the list; delete head; head = tail = nullptr; } else { // if more than one DLLNode in the list; head = head->next; delete head->prev; head->prev = nullptr; } return el; } template T DoublyLinkedList::deleteFromDLLTail() { T el = tail->info; if (head == tail) { // if only one DLLNode on the list; delete head; head = tail = nullptr; } else { // if more than one DLLNode in the list; tail = tail->prev; delete tail->next; tail->next = nullptr; } return el; } template ostream& operator<<(ostream& out, const DoublyLinkedList& dll) { for (DLLNode *tmp = dll.head; tmp != nullptr; tmp = tmp->next) out << tmp->info << ' '; return out; } template T* DoublyLinkedList::find(const T& el) const { for (DLLNode *tmp = head; tmp != nullptr && !(tmp->info == el); // overloaded == tmp = tmp->next); if (tmp == nullptr) return nullptr; else return &tmp->info; } template void DoublyLinkedList::addInMiddle(const T& el) { if (head != nullptr) { if (head->next != nullptr) { int i = 1; for (DLLNode *tmp = head; tmp->next != nullptr; i++, tmp = tmp->next); for (tmp = head, i = i/2; i; i--, tmp = tmp->next); tmp->prev = tmp->prev->next = new DLLNode(el,tmp,tmp->prev); } else head->next = tail = new DLLNode(el,nullptr,head); } else head = tail = new DLLNode(el); } template T& DoublyLinkedList::firstEl() { return head->info; } template void DoublyLinkedList::clear() { for (DLLNode *tmp; head != nullptr; ) { tmp = head; head = head->next; delete tmp; } } #endif