Summary Files Commits Branches @commit @diff @stats
path: root / Year 2 / Structures and data algorithms / HomeworkExamPrep / LinkedList.hpp
diff options
context:
space:
mode:
Commit9d9bd35065ded1d78c9a07af2953e69fc8eb61d4 (patch)
Author
 Syndamia <kamen@syndamia.com>
2023-01-08 22:35:13 +0200
Committer
 Syndamia <kamen@syndamia.com>
2023-01-08 22:35:13 +0200
Files16c6371881423dae7690de56e689171e83bb68ec /Year 2/Structures and data algorithms/HomeworkExamPrep/LinkedList.hpp
uni-projects-9d9bd35065ded1d78c9a07af2953e69fc8eb61d4.tar
uni-projects-9d9bd35065ded1d78c9a07af2953e69fc8eb61d4.tar.gz
uni-projects-9d9bd35065ded1d78c9a07af2953e69fc8eb61d4.zip
Parentf3ee1a0ea95ebbd08dd3dcfe341c649d8ce4a8c1 (diff)
[SDP/HEP] Added preparation for "homework" during class
1 files changed, 230 insertions, 0 deletions
-rw-r--r--Year 2/Structures and data algorithms/HomeworkExamPrep/LinkedList.hpp230
diff --git a/Year 2/Structures and data algorithms/HomeworkExamPrep/LinkedList.hpp b/Year 2/Structures and data algorithms/HomeworkExamPrep/LinkedList.hpp
new file mode 100644
index 0000000..fbab914
--- /dev/null
+++ b/Year 2/Structures and data algorithms/HomeworkExamPrep/LinkedList.hpp
@@ -0,0 +1,230 @@
+#ifndef LINKEDLIST
+#define LINKEDLIST
+
+#include <stdexcept>
+
+template <class T>
+class LinkedList {
+ struct Node {
+ T data;
+ Node* next;
+ Node(const T& data, Node* next = nullptr) : data(data), next(next) {}
+ };
+
+ Node* head;
+ Node* tail;
+ unsigned listSize;
+
+ Node* nodeAt(unsigned index);
+
+public:
+ class Iterator {
+ Node* current;
+ Iterator(Node* current) : current(current) {}
+ public:
+ Iterator& operator++() {
+ if (current == nullptr) return *this;
+
+ current = current->next;
+ return *this;
+ }
+ Iterator operator++(int) {
+ Iterator old = *this;
+ ++(*this);
+ return old;
+ }
+ bool operator==(Iterator& other) {
+ return this->current == other.current;
+ }
+ bool operator!=(Iterator& other) {
+ return !(*this == other);
+ }
+ T& operator*() {
+ return current->data;
+ }
+ friend class LinkedList;
+ };
+ Iterator begin();
+ Iterator end();
+
+ class ConstIterator {
+ const Node* current;
+ ConstIterator(Node* current) : current(current) {}
+ public:
+ ConstIterator& operator++() {
+ if (current == nullptr) return *this;
+
+ current = current->next;
+ return *this;
+ }
+ ConstIterator operator++(int) {
+ ConstIterator old = *this;
+ ++(*this);
+ return old;
+ }
+ bool operator==(const ConstIterator* other) const {
+ return this->current == other->current;
+ }
+ bool operator!=(const ConstIterator* other) const {
+ return !(*this == *other);
+ }
+ const T& operator*() const {
+ return current->data;
+ }
+ friend class LinkedList;
+ };
+ ConstIterator cbegin() const;
+ ConstIterator cend() const;
+
+ void push_front(const T& elem);
+ void push_back(const T& elem);
+ void push_at(unsigned ind, const T& elem);
+ void pop_front();
+ void pop_back();
+ void pop_at(unsigned ind);
+ T& front();
+ unsigned size();
+ bool empty();
+
+
+ LinkedList() : head(nullptr) {}
+ ~LinkedList();
+ LinkedList(LinkedList& other) = delete;
+ LinkedList& operator=(LinkedList& other) = delete;
+};
+
+template <class T>
+typename LinkedList<T>::Iterator LinkedList<T>::begin() {
+ return Iterator(head);
+}
+
+template <class T>
+typename LinkedList<T>::Iterator LinkedList<T>::end() {
+ return Iterator(nullptr);
+}
+
+template <class T>
+typename LinkedList<T>::ConstIterator LinkedList<T>::cbegin() const {
+ return ConstIterator(head);
+}
+
+template <class T>
+typename LinkedList<T>::ConstIterator LinkedList<T>::cend() const {
+ return ConstIterator(nullptr);
+}
+
+template <class T>
+typename LinkedList<T>::Node* LinkedList<T>::nodeAt(unsigned index) {
+ if (index > listSize)
+ throw std::runtime_error("Index too large!");
+
+ Node* nat;
+ for (nat = head; index > 0; index--) {
+ nat = nat->next;
+ }
+ return nat;
+}
+
+template <class T>
+void LinkedList<T>::push_front(const T& elem) {
+ if (empty()) {
+ head = tail = new Node(elem);
+ }
+ else {
+ head = new Node(elem, head);
+ }
+ listSize++;
+}
+
+template <class T>
+void LinkedList<T>::push_back(const T& elem) {
+ if (empty()) {
+ head = tail = new Node(elem);
+ }
+ else {
+ tail = (tail->next = new Node(elem));
+ }
+ listSize++;
+}
+
+template <class T>
+void LinkedList<T>::push_at(unsigned ind, const T& elem) {
+ if (ind >= listSize) {
+ push_back(elem);
+ }
+ else if (ind == 0) {
+ push_front(elem);
+ }
+ else {
+ Node* prev = nodeAt(ind - 1);
+ prev->next = new Node(elem, prev->next);
+ listSize++;
+ }
+}
+
+template <class T>
+void LinkedList<T>::pop_front() {
+ if (empty())
+ throw std::runtime_error("Pop empty list!");
+
+ Node* old = head;
+ head = head->next;
+ delete old;
+ listSize--;
+
+ if (empty()) tail = nullptr;
+}
+
+template <class T>
+void LinkedList<T>::pop_back() {
+ if (empty())
+ throw std::runtime_error("Pop empty list!");
+
+ Node* old = tail;
+ tail = nodeAt(listSize - 2);
+ tail->next = nullptr;
+ delete old;
+ listSize--;
+
+ if (empty()) head = nullptr;
+}
+
+template <class T>
+void LinkedList<T>::pop_at(unsigned ind) {
+ if (ind >= listSize - 1) {
+ pop_back();
+ }
+ else if (ind == 0) {
+ pop_front();
+ }
+ else {
+ Node* prev = nodeAt(ind - 1);
+ Node* curr = prev->next;
+ prev->next = curr->next;
+ delete curr;
+ listSize--;
+ }
+}
+
+template <class T>
+T& LinkedList<T>::front() {
+ return head->data;
+}
+
+template <class T>
+unsigned LinkedList<T>::size() {
+ return listSize;
+}
+
+template <class T>
+bool LinkedList<T>::empty() {
+ return listSize == 0;
+}
+
+template <class T>
+LinkedList<T>::~LinkedList() {
+ while (!empty())
+ pop_front();
+}
+
+#endif