队列的ADT:
template <typename E> class Queue{
private:
void operator =(const Queue&){}
Queue(const Queue&){}
public:
Queue() {}
virtual void clear()=0;
virtual void enqueue(const E&)=0;
virtual E dequeue()=0;
virtual const E& frontValue() const=0;
virtual int length() const=0;
};
1.顺序队列类的实现:
整个数组位置是一个顺时针增长的循环队列。
listArray是一个指向存放队列元素组的指针。为了区分空队列和满队列,数组大小实际要比队列允许的最长长度大1.成员size用来控制队列的循环(它是取模操作符的基数)。成员rear表示当前队尾元素的位置,而front表示当前队首元素的位置。
template <typename E> class AQueue:public Queue<E>{
private:
int maxSize;
int front;
int rear;
E *listArray;
public:
AQueue(int size=defaultSize){
maxSize=size+1;
rear=0;
front=1;
listArray=new E[maxSize];
}
~AQueue(){
delete [] listArray;
}
void clear(){
rear=0;
front=1;
}
void enqueue(const E& it){
Assert(((rear+2)%maxSize)!=front,"Queue is full");
rear=(rear+1)%maxSize;
listArray[rear]=it;
}
E dequeue(){
Assert(length()!=0,"Queue is empty");
E it=listArray[front];
front=(front+1)%maxSize;
return it;
}
const E& frontValue() const {
Assert(length()!=0,"Queue is empty");
E it=listArray[front];
}
virtual int length() const {
return ((rear+maxSize)-front+1)%maxSize;
}
};
2.链式队列类的实现:
成员front和rear分别是指向队首元素和队尾元素的指针。为了简化实现方法,可以使用一个头结点。在初始化时,front和rear同时指向头结点,之后front总是指向头结点,而rear指向队列的尾结点。enqueue只是简单的把新元素放到链表尾部(rear指向的结点),然后修改rear指针指向新的链表结点。dequeue只是简单的删除队列中的第一个结点,并修改front指针。
template <typename E> class LQueue:public Queue<E>{
private:
Link<E>* front;
Link<E>* rear;
int size;
public:
LQueue(int sz=defaultSize){
front=rear=new Link<E>();
size=0;
}
~LQueue() {
clear(); delete front;
}
void clear(){
while(front->next!=NULL){
rear=front;
delete rear;
}
rear=front;
size=0;
}
void enqueue(const E& it){
rear->next=new Link<E>(it,NULL);
rear=rear->next;
size++;
}
void dequeue(){
Assert(size!=0,"Queue is empty");
E it=front->next->element;
Link<E>* ltemp=front->next;
front->next=ltemp->next;
if(rear==ltemp)
rear=front;
delete ltemp;
size--;
return it;
}
const E& frontValue() const {
Assert(size!=0,"Queue is empty");
return front->next->element;
}
virtual int length() const { return size;}
};
3.顺序队列与链式队列的对比:
实现顺序队列和链式队列的所有函数成员都需要常数时间。空间比较问题与栈类似。只是顺序队列不像顺序栈那样,它不能在一个数组里存储两个队列,除非总有数据项从一个队列转入另一个队列。