// ------------------------------------------------------------- // Algoritmos e Estruturas de Dados 2024/2025 - LEIC (FCUP/FEUP) // http://www.dcc.fc.up.pt/~pribeiro/aulas/aed2425/ // ------------------------------------------------------------- // Singly Linked List // Last update: 20/10/2024 // ------------------------------------------------------------- #ifndef SLLIST_H #define SLLIST_H #include #include #include #include // ------------------------------------------------------------- // Simple Node class with a link to the next node // ------------------------------------------------------------- template class Node { private: T value; // value in the node Node *next; // pointer to next node public: Node(const T & v, Node *n): value(v), next(n) {} T & getValue() { return value; } Node *getNext() { return next; } void setValue(T & v) { value=v; } void setNext(Node *n) { next = n; } }; // ------------------------------------------------------------- // Implementation of a SinglyLinkedList // ------------------------------------------------------------- template class SinglyLinkedList { private: Node *first; // first element int length; // length public: // Construtor (creates empty list) SinglyLinkedList(): first(nullptr), length(0) {} // Destrutor ~SinglyLinkedList() { while(!isEmpty()) { assert(first != nullptr && "length bigger than what it should be"); removeFirst(); } assert(first == nullptr && "length smaller than what it should be"); } // Returns the length of the list int size() { return length; } // Returns true iff the list is empty bool isEmpty() { return (length == 0); } // Adds v to the head of the list void addFirst(const T & v) { Node *newNode = new Node(v, first); first = newNode; length++; } // Adds v to the end of the list void addLast(const T & v) { Node *newNode = new Node(v, nullptr); if (isEmpty()) { first = newNode; } else { Node *cur = first; while (cur->getNext() != nullptr) cur = cur->getNext(); cur->setNext(newNode); } length++; } // Returns the reference to the first value T & getFirst() { assert(!isEmpty() && "trying to get first from empty list"); return first->getValue(); } // Returns the last value T & getLast() { assert(!isEmpty() && "trying to get last from empty list"); Node *cur = first; while (cur->getNext() != nullptr) cur = cur->getNext(); return cur->getValue(); } // Removes the first element (does nothing if the list is empty) void removeFirst() { if (isEmpty()) return; Node *victim = first; first = first->getNext(); delete victim; length--; } // Removes the last element (does nothing if the list is empty) void removeLast() { if (isEmpty()) return; if (length == 1) { delete first; first = nullptr; } else { // Using length and a for loop to show an alternative to while loop Node *cur = first; for (int i=0; igetNext(); Node *victim = cur->getNext(); cur->setNext(victim->getNext()); delete victim; } length--; } // Convert a list to a string std::string toString() { if (isEmpty()) return "{}"; std::stringstream sstr; sstr << "{" << first->getValue(); Node *cur = first->getNext(); while (cur != nullptr) { sstr << "," << cur->getValue(); cur = cur->getNext(); } sstr << "}"; std::string str; std::getline(sstr,str); return str; } // ------------------------------------------------------------ // TODO: put the functions you need to implement below this // ------------------------------------------------------------ }; #endif