#include #include #ifndef LINKED_LIST #define LINKED_LIST using namespace std; struct node { int data; node *next; node *previous; }; class List { // private: public: node *head{}; node *tail{}; public: // A default constructor, which creates an empty list List() {} // Not specified in the HW, but needed in my opinion List(node *head, node *tail) : head(head), tail(tail) {} // A parametrized constructor, which creates a list out of the elements of an // array, keeping them in the same given order. List(char *data, size_t n) { for (int i{0}; i < n; i++) appendList(data[i]); } // A copy constructor. List(List const &list) { auto h = list.head; while (h != list.tail->next) { appendList(h->data); h = h->next; } } bool isEmptyList(); std::ostream &printList(std::ostream &out); void prependList(int); void appendList(int); bool findInList(int); void pop(); void popBack(); void removeFromList(node *); void removeFromList(int); friend List operator+(int const a, List const list) { // copy List newlist(list); newlist.prependList(a); return newlist; } friend List operator+(List const list, int a) { // copy List newlist(list); newlist.appendList(a); return newlist; } friend List operator+(List const list1, List const list2) { // copies List newlist1(list1); node *h = list2.head; while (h != list2.tail->next) { newlist1.appendList(h->data); h = h->next; } return newlist1; } node operator[](int i) { auto h = head; for (int j{0}; j < i; j++) h = h->next; return *h; } }; std::ostream &operator<<(std::ostream &out, List list) { return list.printList(out); } bool List::isEmptyList() { if (head == nullptr && tail == nullptr) return true; return false; } void List::appendList(int data) { node *node1 = new node{data, nullptr, tail}; if (head == nullptr && tail == nullptr) { head = node1; tail = node1; } else { tail->next = node1; tail = node1; } } std::ostream &List::printList(std::ostream &out) { if (isEmptyList()) { out << "List is empty" << endl; return out; } node *traveller = head; while (traveller != tail) { out << traveller->data << "=>"; traveller = traveller->next; } out << tail->data << endl; return out; } void List::prependList(int data) { node *node1 = new node{data, head, nullptr}; if (head == nullptr && tail == nullptr) { head = node1; tail = node1; } else { head->previous = node1; head = node1; } } bool List::findInList(int key) { // returns a pointer to the first occurrence of the key in the list node *traveller = head; while (traveller != tail->next) { if (traveller->data == key) { // return traveller; return true; } traveller = traveller->next; } return false; } void List::pop() { if (isEmptyList()) return; if (head == tail) // one node { delete head; head = nullptr; tail = nullptr; return; } node *firstNode = head; head = head->next; head->previous = nullptr; delete firstNode; } void List::popBack() { if (isEmptyList()) return; if (head == tail) // one node { delete head; head = nullptr; tail = nullptr; return; } node *lastNode = tail; tail = tail->previous; tail->next = nullptr; delete lastNode; } void List::removeFromList(node *node1) { if (node1 == head) { pop(); return; } if (node1 == tail) { popBack(); return; } if (node1) { node *tempPrev = node1->previous; node *tempNext = node1->next; tempPrev->next = tempNext; tempNext->previous = tempPrev; delete node1; } } void List::removeFromList(int key) { node *traveller = head; while (traveller != tail->next) { if (traveller->data == key) { removeFromList(traveller); return; } traveller = traveller->next; } // note that this deletes only the first occurrence of the key in the list } #endif