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