INF205/lab_3/sequences-int/singly-linked-list.h
2024-03-09 16:44:29 +01:00

90 lines
3.4 KiB
C++

#ifndef SINGLY_LINKED_LIST_H
#define SINGLY_LINKED_LIST_H
#include <cassert>
#include "sequence.h"
namespace seq
{
class SinglyLinkedListNode
{
public:
// return a reference to the stored item
int& get_item() { return this->item; }
// return pointer to next node, or nullptr if this is the final node
SinglyLinkedListNode* get_next() const { return this->next; }
// overwrite the item stored in this node
void set_item(int in_item) { this->item = in_item; }
private:
int item = 0;
SinglyLinkedListNode* next = nullptr;
// attach a node to this node
// if there was a node attached to this previously, it is NOT deleted!
void set_next(SinglyLinkedListNode* in_next) { this->next = in_next; }
friend class SinglyLinkedList; // allow SinglyLinkedList to access private members
};
class SinglyLinkedList: public Sequence
{
public:
bool empty() const { return (this->head == nullptr); } // test whether the singly linked list is empty
size_t size() const; // return the size (number of items in the singly linked list)
// it is the caller's responsibility to ensure that the list is not empty when calling front() or back()!
int& front() { assert(this->head); return this->head->get_item(); } // return a reference to the first item
int& back() { assert(this->tail); return this->tail->get_item(); } // return a reference to the final item
// return a reference to the item at position i of the list, counting from 0
// it is the caller's responsibility that the index is within range
int& at(int i) { return this->index(i)->get_item(); }
// return pointer to the head/tail node
SinglyLinkedListNode* begin() const { return this->head; }
SinglyLinkedListNode* end() const { return this->tail; }
// return pointer to the node at position i, counting from 0
SinglyLinkedListNode* index(int i) const;
/*
* accepts an additional item into the singly linked list;
* by default, this is done at the back end of the list
* call push_front(...) to push an element at the front
*
* the list takes ownership of the copy (but not of the original!)
*/
void push(const int& pushed_item) { this->push_back(pushed_item); }
void push_back(const int& pushed_item);
void push_front(const int& pushed_item);
/*
* removes an item from the list (front end by default)
* to do the same at the back, call pop_back()
*/
void pop() { this->pop_front(); }
void pop_front();
void pop_back();
void clear() { while(!this->empty()) this->pop(); } // remove all the items from the list
// it is the caller's responsibility that the index is within range
void insert_at(int i, const int& inserted_item); // insert an item at index i
void erase_at(int i); // remove the item at index i
// it is the caller's responsibility that the node is actually part of the list
void insert_successor_to(SinglyLinkedListNode* predecessor, const int& inserted_item); // insert an item after given node
void erase_successor_to(SinglyLinkedListNode* predecessor); // remove the item after given node
~SinglyLinkedList() { this->clear(); }
private:
SinglyLinkedListNode* head = nullptr;
SinglyLinkedListNode* tail = nullptr;
};
}
#endif