#ifndef DEQUE_H_ #define DEQUE_H_ #include #include #include using namespace std; template struct Node { T value; Node *next, *prev; }; template class Deque { public: Deque(); void PushBack(const T& item); void PushFront(const T& item); Node* PopBack(); Node* PopFront(); bool IsEmpty() { return head_ == NULL; } string ToString(); private: Node *head_; Node* MakeNewNode(const T& item, Node* next = 0, Node* prev = 0); }; // From the point of view of the compiler, templates are not normal functions // or classes. They are compiled on demand, meaning that the code of a template // function is not compiled until an instantiation with specific template // arguments is required. // // Because templates are compiled when required, the implementation of a // template class or function must be in the same file as its declaration. template Deque::Deque() { head_ = NULL; } template void Deque::PushFront(const T& item) { Node* new_node; if (head_ == NULL) { new_node = MakeNewNode(item); new_node->next = new_node; new_node->prev = new_node; } else { new_node = MakeNewNode(item, head_, head_->prev); head_->prev->next = new_node; head_->prev = new_node; } head_ = new_node; } template void Deque::PushBack(const T& item) { Node* new_node; if (head_ == NULL) { new_node = MakeNewNode(item); new_node->next = new_node; new_node->prev = new_node; head_ = new_node; } else { new_node = MakeNewNode(item, head_, head_->prev); head_->prev->next = new_node; head_->prev = new_node; } } template Node* Deque::PopFront() { if (head_ == NULL) return NULL; Node* node = head_; if (head_ == head_->next) { head_ = NULL; return node; } head_ = head_->next; head_->prev = node->prev; node->prev->next = head_; return node; } template Node* Deque::PopBack() { if (head_ == NULL) return NULL; Node* node = head_->prev; if (head_ == head_->prev) { head_ = NULL; return node; } head_->prev = node->prev; node->prev->next = head_; return node; } template string Deque::ToString() { ostringstream oss; if (IsEmpty()) return oss.str(); Node* cursor = head_; do { oss << cursor->value << " "; cursor = cursor->next; } while (cursor != head_); return oss.str(); } template Node* Deque::MakeNewNode(const T& item, Node* next, Node* prev) { Node *node = new Node; node->value = item; node->next = next; node->prev = prev; return node; } #endif // DEQUE_H_