#ifndef QUEUE_H
#define QUEUE_H
template<typenameE>classQueue;template<typenameE>classQNode{Edata;QNode<E>*next;QNode<E>*prev;friendclassQueue<E>;QNode():next(nullptr),prev(nullptr){}};template<typenameE>classQueue{public:Queue();~Queue();intsize();boolis_empty();booldequeue();boolenqueue(constE&);boolget_front(E&);boolget_back(E&);private:QNode<E>*header_;// Pointer to the front of the list
QNode<E>*trailer_;// Pointer to the end of the list
intnum_of_nodes_;boolinsert_helper(QNode<E>*,constE&);voidremove_helper(QNode<E>*&);};template<typenameE>Queue<E>::Queue(){// Initialize sentinel nodes.
header_=newQNode<E>;trailer_=newQNode<E>;header_->next=trailer_;trailer_->prev=header_;num_of_nodes_=0;}template<typenameE>Queue<E>::~Queue(){// Delete all nodes, including sentinels.
while(!is_empty())dequeue();deleteheader_;deletetrailer_;}template<typenameE>intQueue<E>::size(){returnnum_of_nodes_;}template<typenameE>boolQueue<E>::is_empty(){// Return true if list is empty, else return false.
returnnum_of_nodes_==0;}template<typenameE>boolQueue<E>::dequeue(){// Call to remove_helper to remove element after header.
if(is_empty())returnfalse;QNode<E>*to_remove=header_->next;remove_helper(to_remove);returntrue;}template<typenameE>voidQueue<E>::remove_helper(QNode<E>*&to_remove){// Delete the node that to_remove points to and link the nodes that are
// its predecessor and successor.
QNode<E>*predecessor=to_remove->prev;QNode<E>*successor=to_remove->next;predecessor->next=successor;successor->prev=predecessor;deleteto_remove;to_remove=nullptr;num_of_nodes_--;}template<typenameE>boolQueue<E>::enqueue(constE&kElement){// Call to insert_helper to insert element before trailer.
returninsert_helper(trailer_->prev,kElement);}template<typenameE>boolQueue<E>::insert_helper(QNode<E>*predecessor,constE&kElement){// Allocate a new node and link it between its predecessor node (the one
// passed in) and its successor node.
QNode<E>*new_node=newQNode<E>;if(new_node==nullptr)returnfalse;new_node->data=kElement;QNode<E>*successor=predecessor->next;predecessor->next=new_node;successor->prev=new_node;new_node->next=successor;new_node->prev=predecessor;num_of_nodes_++;returntrue;}template<typenameE>boolQueue<E>::get_front(E&element){// Aquire the front element.
if(is_empty())returnfalse;element=header_->next->data;returntrue;}template<typenameE>boolQueue<E>::get_back(E&element){// Aquire the back element.
if(is_empty())returnfalse;element=trailer_->prev->data;returntrue;}#endif