This commit is contained in:
unlockable
2023-10-08 00:12:11 +08:00
parent 28fa9faa3f
commit 3ab07283ff

View File

@@ -3,27 +3,21 @@
template <class E> class Node {
private:
E content;
Node *nextNode;
Node<E> *next;
public:
Node();
Node(E _content, Node<E> *_nextNode = NULL);
~Node();
// Returns a reference to the content.
E &getContent();
// Returns a reference to the next Node. May return NULL if this Node is the
// last one.
Node<E> *getNextPtr();
// Set the next Node _nextNode. Returns original pointer.
Node<E> *setNext(Node<E> *_nextNode);
// Returns a reference to the Tail.
Node<E> &getTail();
// Returns a reference to the Node of given index.
Node<E> &getByIndex(const int index);
// Compare the content with the argument.
bool operator==(const E &other);
// Destructs the Node itself and all the node behind it.
void destruct();
Node(const E &_content) : content(_content), next(this){};
Node(const E &_content, Node<E> *nextPtr)
: content(_content), next(nextPtr){};
void setNext(Node<E> *_ptr) {
this->next = _ptr;
}
E &getContent() {
return this->content;
}
Node<E> *getNextPtr() {
return this->next;
}
};
template <class E> class Iterator {
@@ -31,570 +25,97 @@ private:
Node<E> *current;
public:
Iterator(Node<E> *pos);
bool hasNext();
// Return the same as hasNext();
operator bool();
E &next();
E &peek();
Iterator<E> &insertHere(const E &_newItem);
Iterator(Node<E> *start) : current(start){};
E &peekNext() {
return this->current->getNextPtr()->getContent();
}
void next() {
this->current = this->current->getNextPtr();
}
E &peek() {
return this->current->getContent();
}
Node<E> *peekNode() {
return this->current;
}
void insertHere(const E &newItem) {
this->current->setNext(
new Node<E>(newItem, this->current->getNextPtr()));
}
};
template <class E> class List {
private:
Node<E> *head;
int _length;
// int getIndexInRange(int index) const;
// void quickSort(
// int leftBound, int rightBound,
// std::function<bool(const E &, const E &)> const &isCorrectOrderFunc);
// int _length;
Node<E> head;
public:
List();
List(const E &newItem);
List(const E *newItemList, const int itemCount);
List(const List<E> &otherList);
~List();
// Append _newItem at last. Returns the List itself.
List<E> &append(const E &_newItem);
// 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 -
// 1]. Returns the List itself.
List<E> &insert(int index, const E &_newItem);
// Pop the item at given index, default is the to pop the last one.
E pop(int index = -1);
// Remove the first occurance of target. Throws ValueError if target does
// not exist. Returns the List itself.
List<E> &remove(const E &target);
// List<E> &remove(std::function<bool(const E &)> const &isTargetFunc);
// Clear all nodes.
List<E> &clear();
// Swap the element located at index a and b. Throws IndexError if the given
// index is beyond length of the list.
List<E> &swap(int index_a, int index_b);
E &operator[](const int index);
const E &operator[](const int index) const;
List<E> &operator=(const List<E> &otherList);
int length() const;
bool contains(const E &target) const;
// bool contains(std::function<bool(const E &)> const &isTargetFunc) const;
// Give the index of target in the list on its first appearance. Throws
// ValueError if target does not exist.
int index(const E &target) const;
// int index(std::function<bool(const E &)> const &isTargetFunc) const;
// Give the reference to the target in the list on its first appearance.
// E &search(const E &target) const;
// E &search(std::function<bool(const E &)> const &isTargetFunc) const;
// Only retain item that matches the isTargetFunc
// List<E> &filter(std::function<bool(const E &)> const &isTargetFunc);
// Returns a new filtered list.
// const List<E>
// filtered(std::function<bool(const E &)> const &isTargetFunc) const;
// Sort this list.
// List<E> &
// sort(std::function<bool(const E &, const E &)> const
// &isCorrectOrderFunc);
// // Returns a sorted NEW list.
// const List<E> sorted(std::function<bool(const E &, const E &)> const
// &isCorrectOrderFunc) const;
Iterator<E> iterate();
Iterator<E> iterate(int index);
List(const E &dummyValue)
: head(Node<E>(dummyValue)){
// this->_length = 0;
};
// template <class E>
// void List<E>::quickSort(
// int leftBound, int rightBound,
// std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) {
// if (leftBound >= rightBound) {
// return;
// }
// int pivot = leftBound;
// int left = leftBound;
// int right = rightBound;
// while (left < right) {
// while (isCorrectOrderFunc((*this)[pivot], (*this)[right]) &&
// right > left) {
// right--;
// }
// this->swap(pivot, right);
// pivot = right;
// while (isCorrectOrderFunc((*this)[left], (*this)[pivot]) &&
// right > left) {
// left++;
// }
// this->swap(left, pivot);
// pivot = left;
// }
// quickSort(leftBound, pivot - 1, isCorrectOrderFunc);
// quickSort(pivot + 1, rightBound, isCorrectOrderFunc);
// }
template <class E> List<E>::List() : head(NULL), _length(0){};
template <class E>
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) {
for (int i = 0; i < itemCount; i++) {
this->append(newItemList[i]);
void insert(const E &target, const E &newItem) {
Iterator<E> iter = Iterator<E>(&this->head);
// Remember to add a loop to stop at length!!;
while (iter.peek() != target) {
iter.next();
}
};
template <class E> List<E>::List(const List<E> &otherList) {
if (otherList.length() > 0) {
this->head = new Node<E>(otherList[0]);
this->_length = 1;
Node<E> *nextPtr = otherList.head->getNextPtr();
while (nextPtr != NULL) {
this->append((*nextPtr).getContent());
nextPtr = (*nextPtr).getNextPtr();
iter.insertHere(newItem);
// this->_length++;
}
void remove(const E &target) {
Iterator<E> iter = Iterator<E>(&this->head);
while (iter.peekNext() != target) {
iter.next();
}
else {
this->head = NULL;
this->_length = 0;
}
}
template <class E> List<E>::~List() {
if (this->head != NULL) {
this->head->destruct();
}
head = NULL;
}
template <class E> List<E> &List<E>::append(const E &_newItem) {
if (this->head == NULL) {
this->head = new Node<E>(_newItem);
}
else {
this->head->getTail().setNext(new Node<E>(_newItem));
}
this->_length++;
return *this;
}
template <class E> List<E> &List<E>::insert(int index, const E &_newItem) {
// if (index < 0) {
// index += this->_length;
// }
// if (index < 0 || index > _length) {
// throw(IndexError("Index not in range!"));
// }
if (index == 0) {
this->head = new Node<E>(_newItem, this->head);
}
else {
Node<E> &prev = this->head->getByIndex(index - 1);
prev.setNext(new Node<E>(_newItem, prev.getNextPtr()));
}
this->_length++;
return *this;
}
template <class E> List<E> &List<E>::remove(const E &target) {
this->pop(this->index(target));
return *this;
}
template <class E> E List<E>::pop(int index) {
// index = this->getIndexInRange(index);
Node<E> removed = this->head->getByIndex(index);
this->_length--;
if (index == 0) {
Node<E> *newHead = this->head->getNextPtr();
delete this->head;
this->head = newHead;
}
else {
Node<E> &prev = this->head->getByIndex(index - 1);
delete prev.getNextPtr();
prev.setNext(removed.getNextPtr());
}
return removed.getContent();
}
// template <class E>
// List<E> &List<E>::remove(std::function<bool(const E &)> const &isTargetFunc)
// {
// this->pop(this->index(isTargetFunc));
// return *this;
// }
template <class E> List<E> &List<E>::clear() {
if (this->_length == 0) {
return *this;
}
this->head->destruct();
this->head = NULL;
this->_length = 0;
return *this;
}
template <class E> List<E> &List<E>::swap(int index_a, int index_b) {
// index_a = this->getIndexInRange(index_a);
// index_b = this->getIndexInRange(index_b);
if (index_a == index_b) {
return *this;
}
Node<E> *tempPtr;
if (index_a == 0) {
if (index_b == 1) {
Node<E> &A = this->head->getByIndex(0);
Node<E> &B = this->head->getByIndex(1);
Node<E> *afterB = B.getNextPtr();
this->head = &B;
B.setNext(&A);
A.setNext(afterB);
}
else {
Node<E> &A = this->head->getByIndex(index_a);
Node<E> *afterA = A.getNextPtr();
Node<E> &beforeB = this->head->getByIndex(index_b - 1);
Node<E> &B = this->head->getByIndex(index_b);
Node<E> *afterB = B.getNextPtr();
this->head = &B;
beforeB.setNext(&A);
A.setNext(afterB);
B.setNext(afterA);
}
}
else {
if (index_b == index_a + 1) {
Node<E> &beforeA = this->head->getByIndex(index_a - 1);
Node<E> &A = beforeA.getByIndex(1);
Node<E> &B = A.getByIndex(1);
Node<E> *afterB = B.getNextPtr();
beforeA.setNext(&B);
B.setNext(&A);
A.setNext(afterB);
}
else {
Node<E> &beforeA = this->head->getByIndex(index_a - 1);
Node<E> &A = this->head->getByIndex(index_a);
Node<E> *afterA = A.getNextPtr();
Node<E> &beforeB = this->head->getByIndex(index_b - 1);
Node<E> &B = this->head->getByIndex(index_b);
Node<E> *afterB = B.getNextPtr();
beforeA.setNext(&B);
B.setNext(afterA);
beforeB.setNext(&A);
A.setNext(afterB);
}
}
return *this;
}
// template <class E>
// List<E> &List<E>::sort(
// std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) {
// this->quickSort(0, this->_length - 1, isCorrectOrderFunc);
// return *this;
// }
template <class E> E &List<E>::operator[](const int index) {
// return this->head->getByIndex(getIndexInRange(index)).getContent();
return this->head->getByIndex(index).getContent();
}
template <class E> const E &List<E>::operator[](const int index) const {
// return this->head->getByIndex(getIndexInRange(index)).getContent();
return this->head->getByIndex(index).getContent();
}
template <class E> List<E> &List<E>::operator=(const List<E> &otherList) {
this->clear();
if (otherList.length() > 0) {
this->head = new Node<E>(otherList[0]);
this->_length = 1;
Node<E> *nextPtr = otherList.head->getNextPtr();
while (nextPtr != NULL) {
this->append((*nextPtr).getContent());
nextPtr = (*nextPtr).getNextPtr();
}
}
return *this;
}
template <class E> int List<E>::length() const {
return this->_length;
}
template <class E> bool List<E>::contains(const E &target) const {
if (this->_length == 0) {
return false;
}
Node<E> *current = this->head;
do {
if (current->getContent() == target) {
return true;
}
current = current->getNextPtr();
} while (current != NULL);
return false;
}
// template <class E>
// bool List<E>::contains(
// std::function<bool(const E &)> const &isTargetFunc) const {
// if (this->_length == 0) {
// return false;
// }
// Node<E> *current = this->head;
// do {
// if (isTargetFunc(current->getContent())) {
// return true;
// }
// current = current->getNextPtr();
// } while (current != NULL);
// return false;
// }
template <class E> int List<E>::index(const E &target) const {
Node<E> *nextPtr = this->head;
int pos = 0;
while (nextPtr != NULL) {
if (nextPtr->getContent() == target) {
return pos;
}
pos++;
nextPtr = nextPtr->getNextPtr();
}
// throw(ValueError("Target not found!"));
return -1;
}
// template <class E>
// int List<E>::index(std::function<bool(const E &)> const &isTargetFunc) const
// {
// Node<E> *nextPtr = this->head;
// int pos = 0;
// while (nextPtr != NULL) {
// if (isTargetFunc(nextPtr->getContent())) {
// return pos;
// }
// pos++;
// nextPtr = nextPtr->getNextPtr();
// }
// throw(ValueError("Target not found!"));
// }
// template <class E> E &List<E>::search(const E &target) const {
// Node<E> *nextPtr = this->head;
// while (nextPtr != NULL) {
// if (nextPtr->getContent() == target) {
// return nextPtr->getContent();
// }
// nextPtr = nextPtr->getNextPtr();
// }
// throw(ValueError("Target not found!"));
// }
// template <class E>
// E &List<E>::search(std::function<bool(const E &)> const &isTargetFunc) const
// {
// Node<E> *nextPtr = this->head;
// while (nextPtr != NULL) {
// if (isTargetFunc(nextPtr->getContent())) {
// return nextPtr->getContent();
// }
// nextPtr = nextPtr->getNextPtr();
// }
// throw(ValueError("Target not found!"));
// }
// template <class E>
// List<E> &List<E>::filter(std::function<bool(const E &)> const &isTargetFunc)
// {
// if (this->_length == 0) {
// return *this;
// }
// while (this->_length > 0 && !isTargetFunc(this->head->getContent())) {
// Node<E> *newHead = this->head->getNextPtr();
// delete this->head;
// this->head = newHead;
Node<E> *toBeDeleted = iter.peekNode()->getNextPtr();
iter.peekNode()->setNext(toBeDeleted->getNextPtr());
delete toBeDeleted;
// this->_length--;
// }
// if (this->_length == 0) {
// return *this;
// }
// Node<E> *current = this->head;
// while (current->getNextPtr() != NULL) {
// if (!isTargetFunc(current->getNextPtr()->getContent())) {
// Node<E> *newNext = current->getNextPtr()->getNextPtr();
// delete current->getNextPtr();
// current->setNext(newNext);
// continue;
// }
// current = current->getNextPtr();
// }
// return *this;
// }
// template <class E>
// const List<E>
// List<E>::filtered(std::function<bool(const E &)> const &isTargetFunc) const {
// return List<E>(*this).filter(isTargetFunc);
// }
// template <class E>
// const List<E> List<E>::sorted(
// std::function<bool(const E &, const E &)> const &isCorrectOrderFunc)
// const { return List<E>(*this).sort(isCorrectOrderFunc);
// }
template <class E> Iterator<E> List<E>::iterate() {
return Iterator<E>(this->head);
}
template <class E> Iterator<E> List<E>::iterate(int index) {
// index = this->getIndexInRange(index);
if (index == 0) {
return Iterator<E>(this->head);
}
return Iterator<E>(&this->head->getByIndex(index));
}
template <class E> Node<E>::Node() : content(0), nextNode(NULL){};
template <class E>
Node<E>::Node(E _content, Node *_nextNode)
: content(_content), nextNode(_nextNode){};
template <class E> Node<E>::~Node(){};
template <class E> E &Node<E>::getContent() {
return this->content;
}
template <class E> Node<E> *Node<E>::getNextPtr() {
return this->nextNode;
}
template <class E> Node<E> *Node<E>::setNext(Node<E> *_nextNode) {
Node<E> *temp = this->nextNode;
this->nextNode = _nextNode;
return temp;
}
template <class E> Node<E> &Node<E>::getTail() {
if (this->nextNode == NULL) {
return *this;
}
return this->nextNode->getTail();
}
template <class E> Node<E> &Node<E>::getByIndex(const int index) {
if (index == 0) {
return *this;
}
return this->nextNode->getByIndex(index - 1);
}
template <class E> bool Node<E>::operator==(const E &other) {
return this->content == other;
}
template <class E> void Node<E>::destruct() {
if (this->nextNode != NULL) {
this->nextNode->destruct();
}
delete this;
}
template <class E> Iterator<E>::Iterator(Node<E> *start) : current(start){};
template <class E> bool Iterator<E>::hasNext() {
return this->current != NULL;
}
template <class E> Iterator<E>::operator bool() {
return this->hasNext();
}
template <class E> E &Iterator<E>::next() {
// if (!this->hasNext()) {
// throw(IndexError("Out of bound!"));
// }
E &temp = this->current->getContent();
this->current = this->current->getNextPtr();
return temp;
}
template <class E> E &Iterator<E>::peek() {
return this->current->getContent();
}
template <class E> Iterator<E> &Iterator<E>::insertHere(const E &_newItem) {
Node<E>* nextPtr = this->current->getNextPtr();
this->current->setNext(new Node<E>(_newItem, nextPtr));
return *this;
Iterator<E> iterate() {
return Iterator<E>(&this->head);
}
};
int main() {
List<int> aList(1);
List<int> aList(0);
aList.insert(0, 1);
int n;
int cmd, x, y;
scanf("%d", &n);
while (n > 0) {
scanf("%d", &cmd);
while (n) {
scanf("%d %d", &cmd, &x);
switch (cmd) {
case 1: {
scanf("%d %d", &x, &y);
if (x == 0) {
aList.insert(0, y);
break;
}
Iterator<int> iter = aList.iterate();
while (iter) {
if (iter.peek() == x) {
iter.insertHere(y);
break;
}
iter.next();
}
scanf("%d", &y);
aList.insert(x, y);
break;
}
case 2: {
scanf("%d", &x);
Iterator<int> iter = aList.iterate();
while (iter) {
if (iter.next() == x) {
if (iter.hasNext()) {
printf("%d\n", iter.next());
}
else {
printf("0\n");
}
break;
}
while (iter.peek() != x) {
iter.next();
}
printf("%d\n", iter.peekNext());
break;
}
case 3: {
scanf("%d", &x);
aList.remove(x);
break;
}
}
n--;
}
Iterator<int> iter = aList.iterate();
while(iter) {
printf("%d\n", iter.next());
iter.next();
while (true) {
int content = iter.peek();
if (content == 0) {
break;
}
printf("%d\n", content);
iter.next();
}
return 0;
}