队是先进先出的数据结构。需要一头一尾两个指针,front和rear。
template<class T>
class queue
{
public:
virtual ~queue() {}
virtual bool empty() const = 0;
// return true iff queue is empty
virtual int size() const = 0;
// return number of elements in queue
virtual T& front() = 0;
// return reference to the front element
virtual T& back() = 0;
// return reference to the back element
virtual void pop() = 0;
// remove the front element
virtual void push(const T& theElement) = 0;
// add theElement at the back of the queue
};
ArrayQueue
这里采用循环数组存储。location(i)=(location(1)+i-1)%maxsize
循环数组初始化:front=rear=0
循环数组满:(rear+1)%maxsize=front
循环数组最大容量:maxsize-1
template<class T>
class ArrayStack:public queue
{
public:
queue(int capacity=10){
arrayLength=capacity;
front=rear=0;
element=new T[arrayLength];
}
int size(){
return (rear-front+arrayLength)%arrayLength;
}
T& front(){
return element[(front+1)%arrayLength];
}
T& back(){
return element[rear];
}
void pop(){
element[(front+1)%arrayLength].~T();
front=(front+1)%arrayLength;
}
void push(const T& theElement){
//这里在发现数组满的时候并没有采用change1Dlength函数,因为这个数组是循环
//不能单纯的将数组元素从头到尾复制到新的数组,元素的起始位置可能在中间
if(size()==arrayLength-1)
{
int start=(front+1)%arrayLength;
T* newqueue=new T[arrayLength*2];
if(start<2) //此时数组元素在循环数组中都是从头到尾
{
copy(queue+start,queue+start+arraylenth-1,newqueue);
}
else
{
//copy(a,b,n)函数的复制的范围是[a,b)
copy(queue+start,queue+arrayLength,newqueue);
copy(queue,queue+rear+1,newqueue+arrayLength-start);
}
front=arrayLength*2-1;
rear=arrayLength-2;//元素个数是arrayLength-1
arrayLength*=2;
queue=newqueue;
}
rear=(rear+1)%arrayLength;
element[rear]=theElement;
}
private:
//这里也不用定义数组元素大小的变量,可以通过front和rear来计算
int front;
int rear;
T* element;
int arrayLength;
}
LinkedQueue
可以使用链表来实现一个队列,此时需要两个变量front和rear来分别跟踪队列的两端,此时可能有两种情形:从front开始,链接到rear;或者从rear开始,链接到front。不同的链接方式元素删除和插入的难易程度不同,对于添加元素,两种方式的难易程度一样,但是对于删除元素,采用方式a更加方便。因此在用链表来实现队列的时候,我们采用方式a。
class LinkedQueue:public queue{
public:
linkedQueue(){
front=NULL;
rear=NULL;
size=0;
}
~linkedQueue(){
while(front)
{
ListNode* node=front->next;
delete front;
front=node;
}
}
void pop(){
if(empty()) throw ...
ListNode* node=front->next;
delete front;
front=node;
size--;
}
void push(const T& theElement)
{
ListNode* node=new ListNode(theElement);
if(empty()) front=node;
else rear->next=node;
rear=node;
size++;
}
private:
listNode* front;
ListNode* rear;
int size;
}