#ifndef __D_LIST_HPP__ #define __D_LIST_HPP__ #include #include template class dnode { public: T data; dnode* next, * prev; dnode() { next = prev = NULL; } dnode(const T& x) { data = x; next = prev = NULL; } }; template class Itr { private: dnode* current; public: Itr() { current = NULL; } Itr(dnode* ptr) { current = ptr; } Itr& operator++(); //pre-increment x = ++i; // i = 1; x = 2 Itr operator++(int); //post-increment y = i++; // i = 1; y = 1 Itr& operator--(); //pre-decrement --i Itr operator--(int); //post-decrement i-- T operator*() const { return current->data; }; T& operator*() { return current->data; }; const dnode* operator->() const { return current; }; dnode* operator->() { return current; }; }; //pre-increment ++i template Itr& Itr::operator++() { if (current != NULL) current = current->next; return *this; // return the iterator after the movement } //post-increment template Itr Itr::operator++(int) { Itr itr(current); if (current != NULL) current = current->next; return itr; // return the original iterator } //pre-decrement --i template Itr& Itr::operator--() { if (current != NULL) current = current->prev; return *this; // return the iterator after the movement } //post-decrement template Itr Itr::operator--(int) { Itr itr(current); if (current != NULL) current = current->prev; return itr; // return the original iterator } template class DList { private: dnode* front, * rear; public: DList() { front = rear = NULL; } DList(T elem) { dnode* newNode = new dnode(elem); front = rear = newNode; } DList(const DList& list2); ~DList(); Itr& operator[](int index); const Itr operator[](const int index) const; Itr begin() { Itr tmp(front); return tmp; } Itr end() { Itr tmp(rear); return tmp; } bool isEmpty() { return front == NULL; } void insertBeforeNode(const T& elem, Itr cur); void insertAfterNode(const T&elem, Itr cur); void remove(Itr cur); }; template Itr& DList::operator[](int index) { dnode* temp = front; for (int i = 0; i <= index; i++) { if (temp == NULL) break; temp = temp->next; } Itr itr(temp); return itr; } template const Itr DList::operator[](const int index) const { Itr itr(front); for (int i = 0; i <= index; i++) { if (itr.operator->() == NULL) break; itr++; } return itr; } template void DList::insertBeforeNode(const T& elem, Itr cur) { dnode* newNode = new dnode(elem); // if the list is empty if (front == NULL) { front = rear = newNode; } else { // if cur is the first node in the list if (cur.operator->() == front) { newNode->next = front; front->prev = newNode; front = newNode; } else { newNode->next = cur.operator->(); newNode->prev = cur->prev; cur->prev->next = newNode; cur->prev = newNode; } } } template void DList::insertAfterNode(const T& elem, Itr cur) { dnode* newNode = new dnode(elem); // if the list is empty if (front == NULL) { front = rear = newNode; } else { // if cur is the last node in the list if (cur.operator->() == rear) { newNode->prev = rear; rear->next = newNode; rear = newNode; } else { newNode->next = cur->next; newNode->prev = cur.operator->(); cur->next->prev = newNode; cur->next = newNode; } } } template void DList::remove(Itr cur) { assert(!isEmpty()); if (cur.operator->() == front) { // removing the front node front = front->next; } else { // Step 1, update the next pointer of previous node cur->prev->next = cur->next; } if (cur.operator->() == rear) { rear = rear->prev; } else { // Step 2, update the previous pointer of next node cur->next->prev = cur->prev; } /* // Step 1, update the next pointer of previous node cur->prev->next = cur->next; // Step 2, update the previous pointer of next node cur->next->prev = cur->prev; */ // Step 3, delete the node delete cur.operator->(); } template DList::DList(const DList& list2) { // list2 is empty if (list2.front == NULL) { front = rear = NULL; } else { front = rear = NULL; dnode* temp = list2.front; while (temp != NULL) { dnode* newNode = new dnode(temp->data); if (front == NULL) { front = rear = newNode; } else { rear->next = newNode; newNode->prev = rear; rear = newNode; } temp = temp->next; } } } template DList::~DList() { dnode* temp; while (front != NULL) { temp = front; front = front->next; delete temp; } } #endif