更改文件夹名。

This commit is contained in:
unlockable
2023-06-24 17:31:16 +08:00
parent ce89b63b8e
commit 1c58758515
19 changed files with 538 additions and 538 deletions

866
大作业/ListE.hpp → FinalProject/ListE.hpp Executable file → Normal file
View File

@@ -1,434 +1,434 @@
#pragma once #pragma once
#include "Exceptions.hpp" #include "Exceptions.hpp"
#include "Node.hpp" #include "Node.hpp"
#include <functional> #include <functional>
template <class E> class List { template <class E> class List {
private: private:
Node<E> *head; Node<E> *head;
int _length; int _length;
int getIndexInRange(int index) const; int getIndexInRange(int index) const;
void quickSort( void quickSort(
int leftBound, int rightBound, int leftBound, int rightBound,
std::function<bool(const E &, const E &)> const &isCorrentOrderFunc); std::function<bool(const E &, const E &)> const &isCorrentOrderFunc);
public: public:
List(); List();
List(const E &newItem); List(const E &newItem);
List(const E *newItemList, const int itemCount); List(const E *newItemList, const int itemCount);
List(const List<E> &otherList); List(const List<E> &otherList);
~List(); ~List();
// Append _newItem at last. Returns the List itself. // Append _newItem at last. Returns the List itself.
List<E> &append(const E &_newItem); List<E> &append(const E &_newItem);
// Insert _newItem at index, and move all items at and after [index] 1 step. // Insert _newItem at index, and move all items at and after [index] 1 step.
// Throws IndexError if index is not in the range of [-_length, _length - // Throws IndexError if index is not in the range of [-_length, _length -
// 1]. Returns the List itself. // 1]. Returns the List itself.
List<E> &insert(int index, const E &_newItem); List<E> &insert(int index, const E &_newItem);
// Pop the item at given index, default is the to pop the last one. // Pop the item at given index, default is the to pop the last one.
E pop(int index = -1); E pop(int index = -1);
// Remove the first occurance of target. Throws ValueError if target does // Remove the first occurance of target. Throws ValueError if target does
// not exist. Returns the List itself. // not exist. Returns the List itself.
List<E> &remove(const E &target); List<E> &remove(const E &target);
List<E> &remove(std::function<bool(const E &)> const &isTargetFunc); List<E> &remove(std::function<bool(const E &)> const &isTargetFunc);
// Clear all nodes. // Clear all nodes.
List<E> &clear(); List<E> &clear();
// Swap the element located at index a and b. Throws IndexError if the given // Swap the element located at index a and b. Throws IndexError if the given
// index is beyond length of the list. // index is beyond length of the list.
List<E> &swap(int index_a, int index_b); List<E> &swap(int index_a, int index_b);
E &operator[](const int index); E &operator[](const int index);
const E &operator[](const int index) const; const E &operator[](const int index) const;
List<E> &operator=(const List<E> &otherList); List<E> &operator=(const List<E> &otherList);
int length() const; int length() const;
bool contains(const E &target) const; bool contains(const E &target) const;
bool contains(std::function<bool(const E &)> const &isTargetFunc) const; bool contains(std::function<bool(const E &)> const &isTargetFunc) const;
// Give the index of target in the list on its first appearance. Throws // Give the index of target in the list on its first appearance. Throws
// ValueError if target does not exist. // ValueError if target does not exist.
int index(const E &target) const; int index(const E &target) const;
int index(std::function<bool(const E &)> const &isTargetFunc) const; int index(std::function<bool(const E &)> const &isTargetFunc) const;
// Give the reference to the target in the list on its first appearance. // Give the reference to the target in the list on its first appearance.
E &search(const E &target) const; E &search(const E &target) const;
E &search(std::function<bool(const E &)> const &isTargetFunc) const; E &search(std::function<bool(const E &)> const &isTargetFunc) const;
// Only retain item that matches the isTargetFunc // Only retain item that matches the isTargetFunc
List<E> &filter(std::function<bool(const E &)> const &isTargetFunc); List<E> &filter(std::function<bool(const E &)> const &isTargetFunc);
// Returns a new filtered list. // Returns a new filtered list.
const List<E> const List<E>
filtered(std::function<bool(const E &)> const &isTargetFunc) const; filtered(std::function<bool(const E &)> const &isTargetFunc) const;
// Sort this list. // Sort this list.
List<E> & List<E> &
sort(std::function<bool(const E &, const E &)> const &isCorrectOrderFunc); sort(std::function<bool(const E &, const E &)> const &isCorrectOrderFunc);
// Returns a sorted NEW list. // Returns a sorted NEW list.
const List<E> sorted(std::function<bool(const E &, const E &)> const const List<E> sorted(std::function<bool(const E &, const E &)> const
&isCorrectOrderFunc) const; &isCorrectOrderFunc) const;
Iterator<E> &&iterate(); Iterator<E> &&iterate();
Iterator<E> &&iterate(int index); Iterator<E> &&iterate(int index);
}; };
template <class E> int List<E>::getIndexInRange(int index) const { template <class E> int List<E>::getIndexInRange(int index) const {
if (index < 0) { if (index < 0) {
index += this->_length; index += this->_length;
} }
if (index < 0 || index >= _length) { if (index < 0 || index >= _length) {
throw(IndexError("Index not in range!")); throw(IndexError("Index not in range!"));
} }
return index; return index;
} }
template <class E> template <class E>
void List<E>::quickSort( void List<E>::quickSort(
int leftBound, int rightBound, int leftBound, int rightBound,
std::function<bool(const E &, const E &)> const &isCorrentOrderFunc) { std::function<bool(const E &, const E &)> const &isCorrentOrderFunc) {
if (leftBound >= rightBound) { if (leftBound >= rightBound) {
return; return;
} }
int pivot = leftBound; int pivot = leftBound;
int left = leftBound; int left = leftBound;
int right = rightBound; int right = rightBound;
while (left < right) { while (left < right) {
while (isCorrentOrderFunc((*this)[pivot], (*this)[right]) && while (isCorrentOrderFunc((*this)[pivot], (*this)[right]) &&
right > left) { right > left) {
right--; right--;
} }
this->swap(pivot, right); this->swap(pivot, right);
pivot = right; pivot = right;
while (isCorrentOrderFunc((*this)[left], (*this)[pivot]) && while (isCorrentOrderFunc((*this)[left], (*this)[pivot]) &&
right > left) { right > left) {
left++; left++;
} }
this->swap(left, pivot); this->swap(left, pivot);
pivot = left; pivot = left;
} }
quickSort(leftBound, pivot - 1, isCorrentOrderFunc); quickSort(leftBound, pivot - 1, isCorrentOrderFunc);
quickSort(pivot + 1, rightBound, isCorrentOrderFunc); quickSort(pivot + 1, rightBound, isCorrentOrderFunc);
} }
template <class E> List<E>::List() : head(NULL), _length(0){}; template <class E> List<E>::List() : head(NULL), _length(0){};
template <class E> template <class E>
List<E>::List(const E &newItem) : head(new Node<E>(newItem)), _length(1){}; List<E>::List(const E &newItem) : head(new Node<E>(newItem)), _length(1){};
template <class E> List<E>::List(const E *newItemList, const int itemCount) { template <class E> List<E>::List(const E *newItemList, const int itemCount) {
for (int i = 0; i < itemCount; i++) { for (int i = 0; i < itemCount; i++) {
this->append(newItemList[i]); this->append(newItemList[i]);
} }
}; };
template <class E> List<E>::List(const List<E> &otherList) { template <class E> List<E>::List(const List<E> &otherList) {
if (otherList.length() > 0) { if (otherList.length() > 0) {
this->head = new Node<E>(otherList[0]); this->head = new Node<E>(otherList[0]);
this->_length = 1; this->_length = 1;
Node<E> *nextPtr = otherList.head->getNextPtr(); Node<E> *nextPtr = otherList.head->getNextPtr();
while (nextPtr != NULL) { while (nextPtr != NULL) {
this->append((*nextPtr).getContent()); this->append((*nextPtr).getContent());
nextPtr = (*nextPtr).getNextPtr(); nextPtr = (*nextPtr).getNextPtr();
} }
} }
else { else {
this->head = NULL; this->head = NULL;
this->_length = 0; this->_length = 0;
} }
} }
template <class E> List<E>::~List() { template <class E> List<E>::~List() {
if (this->head != NULL) { if (this->head != NULL) {
this->head->destruct(); this->head->destruct();
} }
head = NULL; head = NULL;
} }
template <class E> List<E> &List<E>::append(const E &_newItem) { template <class E> List<E> &List<E>::append(const E &_newItem) {
if (this->head == NULL) { if (this->head == NULL) {
this->head = new Node<E>(_newItem); this->head = new Node<E>(_newItem);
} }
else { else {
this->head->getTail().setNext(new Node<E>(_newItem)); this->head->getTail().setNext(new Node<E>(_newItem));
} }
this->_length++; this->_length++;
return *this; return *this;
} }
template <class E> List<E> &List<E>::insert(int index, const E &_newItem) { template <class E> List<E> &List<E>::insert(int index, const E &_newItem) {
if (index < 0) { if (index < 0) {
index += this->_length; index += this->_length;
} }
if (index < 0 || index > _length) { if (index < 0 || index > _length) {
throw(IndexError("Index not in range!")); throw(IndexError("Index not in range!"));
} }
if (index == 0) { if (index == 0) {
this->head = new Node<E>(_newItem, this->head); this->head = new Node<E>(_newItem, this->head);
} }
else { else {
Node<E> &prev = this->head->getByIndex(index - 1); Node<E> &prev = this->head->getByIndex(index - 1);
prev.setNext(new Node<E>(_newItem, prev.getNextPtr())); prev.setNext(new Node<E>(_newItem, prev.getNextPtr()));
} }
this->_length++; this->_length++;
return *this; return *this;
} }
template <class E> List<E> &List<E>::remove(const E &target) { template <class E> List<E> &List<E>::remove(const E &target) {
this->pop(this->index(target)); this->pop(this->index(target));
return *this; return *this;
} }
template <class E> E List<E>::pop(int index) { template <class E> E List<E>::pop(int index) {
index = this->getIndexInRange(index); index = this->getIndexInRange(index);
Node<E> removed = this->head->getByIndex(index); Node<E> removed = this->head->getByIndex(index);
this->_length--; this->_length--;
if (index == 0) { if (index == 0) {
Node<E> *newHead = this->head->getNextPtr(); Node<E> *newHead = this->head->getNextPtr();
delete this->head; delete this->head;
this->head = newHead; this->head = newHead;
} }
else { else {
Node<E> &prev = this->head->getByIndex(index - 1); Node<E> &prev = this->head->getByIndex(index - 1);
delete prev.getNextPtr(); delete prev.getNextPtr();
prev.setNext(removed.getNextPtr()); prev.setNext(removed.getNextPtr());
} }
return removed.getContent(); return removed.getContent();
} }
template <class E> template <class E>
List<E> &List<E>::remove(std::function<bool(const E &)> const &isTargetFunc) { List<E> &List<E>::remove(std::function<bool(const E &)> const &isTargetFunc) {
this->pop(this->index(isTargetFunc)); this->pop(this->index(isTargetFunc));
return *this; return *this;
} }
template <class E> List<E> &List<E>::clear() { template <class E> List<E> &List<E>::clear() {
if (this->_length == 0) { if (this->_length == 0) {
return *this; return *this;
} }
this->head->destruct(); this->head->destruct();
this->head = NULL; this->head = NULL;
this->_length = 0; this->_length = 0;
return *this; return *this;
} }
template <class E> List<E> &List<E>::swap(int index_a, int index_b) { template <class E> List<E> &List<E>::swap(int index_a, int index_b) {
index_a = this->getIndexInRange(index_a); index_a = this->getIndexInRange(index_a);
index_b = this->getIndexInRange(index_b); index_b = this->getIndexInRange(index_b);
if (index_a == index_b) { if (index_a == index_b) {
return *this; return *this;
} }
Node<E> *tempPtr; Node<E> *tempPtr;
if (index_a == 0) { if (index_a == 0) {
if (index_b == 1) { if (index_b == 1) {
Node<E> &A = this->head->getByIndex(0); Node<E> &A = this->head->getByIndex(0);
Node<E> &B = this->head->getByIndex(1); Node<E> &B = this->head->getByIndex(1);
Node<E> *afterB = B.getNextPtr(); Node<E> *afterB = B.getNextPtr();
this->head = &B; this->head = &B;
B.setNext(&A); B.setNext(&A);
A.setNext(afterB); A.setNext(afterB);
} }
else { else {
Node<E> &A = this->head->getByIndex(index_a); Node<E> &A = this->head->getByIndex(index_a);
Node<E> *afterA = A.getNextPtr(); Node<E> *afterA = A.getNextPtr();
Node<E> &beforeB = this->head->getByIndex(index_b - 1); Node<E> &beforeB = this->head->getByIndex(index_b - 1);
Node<E> &B = this->head->getByIndex(index_b); Node<E> &B = this->head->getByIndex(index_b);
Node<E> *afterB = B.getNextPtr(); Node<E> *afterB = B.getNextPtr();
this->head = &B; this->head = &B;
beforeB.setNext(&A); beforeB.setNext(&A);
A.setNext(afterB); A.setNext(afterB);
B.setNext(afterA); B.setNext(afterA);
} }
} }
else { else {
if (index_b == index_a + 1) { if (index_b == index_a + 1) {
Node<E> &beforeA = this->head->getByIndex(index_a - 1); Node<E> &beforeA = this->head->getByIndex(index_a - 1);
Node<E> &A = beforeA.getByIndex(1); Node<E> &A = beforeA.getByIndex(1);
Node<E> &B = A.getByIndex(1); Node<E> &B = A.getByIndex(1);
Node<E> *afterB = B.getNextPtr(); Node<E> *afterB = B.getNextPtr();
beforeA.setNext(&B); beforeA.setNext(&B);
B.setNext(&A); B.setNext(&A);
A.setNext(afterB); A.setNext(afterB);
} }
else { else {
Node<E> &beforeA = this->head->getByIndex(index_a - 1); Node<E> &beforeA = this->head->getByIndex(index_a - 1);
Node<E> &A = this->head->getByIndex(index_a); Node<E> &A = this->head->getByIndex(index_a);
Node<E> *afterA = A.getNextPtr(); Node<E> *afterA = A.getNextPtr();
Node<E> &beforeB = this->head->getByIndex(index_b - 1); Node<E> &beforeB = this->head->getByIndex(index_b - 1);
Node<E> &B = this->head->getByIndex(index_b); Node<E> &B = this->head->getByIndex(index_b);
Node<E> *afterB = B.getNextPtr(); Node<E> *afterB = B.getNextPtr();
beforeA.setNext(&B); beforeA.setNext(&B);
B.setNext(afterA); B.setNext(afterA);
beforeB.setNext(&A); beforeB.setNext(&A);
A.setNext(afterB); A.setNext(afterB);
} }
} }
return *this; return *this;
} }
template <class E> template <class E>
List<E> &List<E>::sort( List<E> &List<E>::sort(
std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) { std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) {
this->quickSort(0, this->_length - 1, isCorrectOrderFunc); this->quickSort(0, this->_length - 1, isCorrectOrderFunc);
return *this; return *this;
} }
template <class E> E &List<E>::operator[](const int index) { template <class E> E &List<E>::operator[](const int index) {
return this->head->getByIndex(getIndexInRange(index)).getContent(); return this->head->getByIndex(getIndexInRange(index)).getContent();
} }
template <class E> const E &List<E>::operator[](const int index) const { template <class E> const E &List<E>::operator[](const int index) const {
return this->head->getByIndex(getIndexInRange(index)).getContent(); return this->head->getByIndex(getIndexInRange(index)).getContent();
} }
template <class E> List<E> &List<E>::operator=(const List<E> &otherList) { template <class E> List<E> &List<E>::operator=(const List<E> &otherList) {
this->clear(); this->clear();
if (otherList.length() > 0) { if (otherList.length() > 0) {
this->head = new Node<E>(otherList[0]); this->head = new Node<E>(otherList[0]);
this->_length = 1; this->_length = 1;
Node<E> *nextPtr = otherList.head->getNextPtr(); Node<E> *nextPtr = otherList.head->getNextPtr();
while (nextPtr != NULL) { while (nextPtr != NULL) {
this->append((*nextPtr).getContent()); this->append((*nextPtr).getContent());
nextPtr = (*nextPtr).getNextPtr(); nextPtr = (*nextPtr).getNextPtr();
} }
} }
return *this; return *this;
} }
template <class E> int List<E>::length() const { template <class E> int List<E>::length() const {
return this->_length; return this->_length;
} }
template <class E> bool List<E>::contains(const E &target) const { template <class E> bool List<E>::contains(const E &target) const {
if (this->_length == 0) { if (this->_length == 0) {
return false; return false;
} }
Node<E> *current = this->head; Node<E> *current = this->head;
do { do {
if (current->getContent() == target) { if (current->getContent() == target) {
return true; return true;
} }
current = current->getNextPtr(); current = current->getNextPtr();
} while (current != NULL); } while (current != NULL);
return false; return false;
} }
template <class E> template <class E>
bool List<E>::contains( bool List<E>::contains(
std::function<bool(const E &)> const &isTargetFunc) const { std::function<bool(const E &)> const &isTargetFunc) const {
if (this->_length == 0) { if (this->_length == 0) {
return false; return false;
} }
Node<E> *current = this->head; Node<E> *current = this->head;
do { do {
if (isTargetFunc(current->getContent())) { if (isTargetFunc(current->getContent())) {
return true; return true;
} }
current = current->getNextPtr(); current = current->getNextPtr();
} while (current != NULL); } while (current != NULL);
return false; return false;
} }
template <class E> int List<E>::index(const E &target) const { template <class E> int List<E>::index(const E &target) const {
Node<E> *nextPtr = this->head; Node<E> *nextPtr = this->head;
int pos = 0; int pos = 0;
while (nextPtr != NULL) { while (nextPtr != NULL) {
if (nextPtr->getContent() == target) { if (nextPtr->getContent() == target) {
return pos; return pos;
} }
pos++; pos++;
nextPtr = nextPtr->getNextPtr(); nextPtr = nextPtr->getNextPtr();
} }
throw(ValueError("Target not found!")); throw(ValueError("Target not found!"));
} }
template <class E> template <class E>
int List<E>::index(std::function<bool(const E &)> const &isTargetFunc) const { int List<E>::index(std::function<bool(const E &)> const &isTargetFunc) const {
Node<E> *nextPtr = this->head; Node<E> *nextPtr = this->head;
int pos = 0; int pos = 0;
while (nextPtr != NULL) { while (nextPtr != NULL) {
if (isTargetFunc(nextPtr->getContent())) { if (isTargetFunc(nextPtr->getContent())) {
return pos; return pos;
} }
pos++; pos++;
nextPtr = nextPtr->getNextPtr(); nextPtr = nextPtr->getNextPtr();
} }
throw(ValueError("Target not found!")); throw(ValueError("Target not found!"));
} }
template <class E> E &List<E>::search(const E &target) const { template <class E> E &List<E>::search(const E &target) const {
Node<E> *nextPtr = this->head; Node<E> *nextPtr = this->head;
while (nextPtr != NULL) { while (nextPtr != NULL) {
if (nextPtr->getContent() == target) { if (nextPtr->getContent() == target) {
return nextPtr->getContent(); return nextPtr->getContent();
} }
nextPtr = nextPtr->getNextPtr(); nextPtr = nextPtr->getNextPtr();
} }
throw(ValueError("Target not found!")); throw(ValueError("Target not found!"));
} }
template <class E> template <class E>
E &List<E>::search(std::function<bool(const E &)> const &isTargetFunc) const { E &List<E>::search(std::function<bool(const E &)> const &isTargetFunc) const {
Node<E> *nextPtr = this->head; Node<E> *nextPtr = this->head;
while (nextPtr != NULL) { while (nextPtr != NULL) {
if (isTargetFunc(nextPtr->getContent())) { if (isTargetFunc(nextPtr->getContent())) {
return nextPtr->getContent(); return nextPtr->getContent();
} }
nextPtr = nextPtr->getNextPtr(); nextPtr = nextPtr->getNextPtr();
} }
throw(ValueError("Target not found!")); throw(ValueError("Target not found!"));
} }
template <class E> template <class E>
List<E> &List<E>::filter(std::function<bool(const E &)> const &isTargetFunc) { List<E> &List<E>::filter(std::function<bool(const E &)> const &isTargetFunc) {
if (this->_length == 0) { if (this->_length == 0) {
return *this; return *this;
} }
while (this->_length > 0 && !isTargetFunc(this->head->getContent())) { while (this->_length > 0 && !isTargetFunc(this->head->getContent())) {
Node<E> *newHead = this->head->getNextPtr(); Node<E> *newHead = this->head->getNextPtr();
delete this->head; delete this->head;
this->head = newHead; this->head = newHead;
this->_length--; this->_length--;
} }
if (this->_length == 0) { if (this->_length == 0) {
return *this; return *this;
} }
Node<E> *current = this->head; Node<E> *current = this->head;
while (current->getNextPtr() != NULL) { while (current->getNextPtr() != NULL) {
if (!isTargetFunc(current->getNextPtr()->getContent())) { if (!isTargetFunc(current->getNextPtr()->getContent())) {
Node<E> *newNext = current->getNextPtr()->getNextPtr(); Node<E> *newNext = current->getNextPtr()->getNextPtr();
delete current->getNextPtr(); delete current->getNextPtr();
current->setNext(newNext); current->setNext(newNext);
continue; continue;
} }
current = current->getNextPtr(); current = current->getNextPtr();
} }
return *this; return *this;
} }
template <class E> template <class E>
const List<E> const List<E>
List<E>::filtered(std::function<bool(const E &)> const &isTargetFunc) const { List<E>::filtered(std::function<bool(const E &)> const &isTargetFunc) const {
return List<E>(*this).filter(isTargetFunc); return List<E>(*this).filter(isTargetFunc);
} }
template <class E> template <class E>
const List<E> List<E>::sorted( const List<E> List<E>::sorted(
std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) const { std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) const {
return List<E>(*this).sort(isCorrectOrderFunc); return List<E>(*this).sort(isCorrectOrderFunc);
} }
template <class E> Iterator<E> &&List<E>::iterate() { template <class E> Iterator<E> &&List<E>::iterate() {
return std::move(Iterator<E>(this->head)); return std::move(Iterator<E>(this->head));
} }
template <class E> Iterator<E> &&List<E>::iterate(int index) { template <class E> Iterator<E> &&List<E>::iterate(int index) {
index = this->getIndexInRange(index); index = this->getIndexInRange(index);
if (index == 0) { if (index == 0) {
return std::move(Iterator<E>(this->head)); return std::move(Iterator<E>(this->head));
} }
return std::move(Iterator<E>(&this->head->getByIndex(index))); return std::move(Iterator<E>(&this->head->getByIndex(index)));
} }

210
大作业/Node.hpp → FinalProject/Node.hpp Executable file → Normal file
View File

@@ -1,106 +1,106 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
template <class E> class Node { template <class E> class Node {
private: private:
E content; E content;
Node *nextNode; Node *nextNode;
public: public:
Node(); Node();
Node(E _content, Node<E> *_nextNode = NULL); Node(E _content, Node<E> *_nextNode = NULL);
~Node(); ~Node();
// Returns a reference to the content. // Returns a reference to the content.
E &getContent(); E &getContent();
// Returns a reference to the next Node. May return NULL if this Node is the // Returns a reference to the next Node. May return NULL if this Node is the
// last one. // last one.
Node<E> *getNextPtr(); Node<E> *getNextPtr();
// Set the next Node _nextNode. Returns original pointer. // Set the next Node _nextNode. Returns original pointer.
Node<E> *setNext(Node<E> *_nextNode); Node<E> *setNext(Node<E> *_nextNode);
// Returns a reference to the Tail. // Returns a reference to the Tail.
Node<E> &getTail(); Node<E> &getTail();
// Returns a reference to the Node of given index. // Returns a reference to the Node of given index.
Node<E> &getByIndex(const int index); Node<E> &getByIndex(const int index);
// Compare the content with the argument. // Compare the content with the argument.
bool operator==(const E &other); bool operator==(const E &other);
// Destructs the Node itself and all the node behind it. // Destructs the Node itself and all the node behind it.
void destruct(); void destruct();
}; };
template <class E> class Iterator { template <class E> class Iterator {
private: private:
Node<E> *current; Node<E> *current;
public: public:
Iterator(Node<E> *pos); Iterator(Node<E> *pos);
bool hasNext(); bool hasNext();
// Return the same as hasNext(); // Return the same as hasNext();
operator bool(); operator bool();
E &next(); E &next();
}; };
template <class E> Node<E>::Node() : content(0), nextNode(NULL){}; template <class E> Node<E>::Node() : content(0), nextNode(NULL){};
template <class E> template <class E>
Node<E>::Node(E _content, Node *_nextNode) Node<E>::Node(E _content, Node *_nextNode)
: content(_content), nextNode(_nextNode){}; : content(_content), nextNode(_nextNode){};
template <class E> Node<E>::~Node(){}; template <class E> Node<E>::~Node(){};
template <class E> E &Node<E>::getContent() { template <class E> E &Node<E>::getContent() {
return this->content; return this->content;
} }
template <class E> Node<E> *Node<E>::getNextPtr() { template <class E> Node<E> *Node<E>::getNextPtr() {
return this->nextNode; return this->nextNode;
} }
template <class E> Node<E> *Node<E>::setNext(Node<E> *_nextNode) { template <class E> Node<E> *Node<E>::setNext(Node<E> *_nextNode) {
Node<E> *temp = this->nextNode; Node<E> *temp = this->nextNode;
this->nextNode = _nextNode; this->nextNode = _nextNode;
return temp; return temp;
} }
template <class E> Node<E> &Node<E>::getTail() { template <class E> Node<E> &Node<E>::getTail() {
if (this->nextNode == NULL) { if (this->nextNode == NULL) {
return *this; return *this;
} }
return this->nextNode->getTail(); return this->nextNode->getTail();
} }
template <class E> Node<E> &Node<E>::getByIndex(const int index) { template <class E> Node<E> &Node<E>::getByIndex(const int index) {
if (index == 0) { if (index == 0) {
return *this; return *this;
} }
return this->nextNode->getByIndex(index - 1); return this->nextNode->getByIndex(index - 1);
} }
template <class E> bool Node<E>::operator==(const E &other) { template <class E> bool Node<E>::operator==(const E &other) {
return this->content == other; return this->content == other;
} }
template <class E> void Node<E>::destruct() { template <class E> void Node<E>::destruct() {
if (this->nextNode != NULL) { if (this->nextNode != NULL) {
this->nextNode->destruct(); this->nextNode->destruct();
} }
delete this; delete this;
} }
template <class E> Iterator<E>::Iterator(Node<E> *start) : current(start){}; template <class E> Iterator<E>::Iterator(Node<E> *start) : current(start){};
template <class E> bool Iterator<E>::hasNext() { template <class E> bool Iterator<E>::hasNext() {
return this->current != NULL; return this->current != NULL;
} }
template <class E> Iterator<E>::operator bool() { template <class E> Iterator<E>::operator bool() {
return this->hasNext(); return this->hasNext();
} }
template <class E> E &Iterator<E>::next() { template <class E> E &Iterator<E>::next() {
if (!this->hasNext()) { if (!this->hasNext()) {
throw(IndexError("Out of bound!")); throw(IndexError("Out of bound!"));
} }
E &temp = this->current->getContent(); E &temp = this->current->getContent();
this->current = this->current->getNextPtr(); this->current = this->current->getNextPtr();
return temp; return temp;
} }