要开始学习队列啦~(鬼知道我为什么这么开心)
首先,老规矩,在开始前,先给出队列的抽象类
template<class T>
class queue
{
public:
virtual ~queue(){}
virtual bool empty()const=0;//返回true,当且仅当队列为空
virtual int size()const=0;//返回队列中元素个数
virtual T& front()=0;//返回头元素的引用
virtual T& back()=0;//返回尾元素的引用
virtual void pop()=0;//删除首元素
virtual void push(const T& theElement)=0;//把元素theElement加入队尾
};
队列的数组描述可以写成循环数组,重点是队列是否满了的判断。
如果队列插满,则队列为空和队列满的判断条件一样,为了避免这种情况,队列不能插满,用这种方法,队列元素个数最多是arrayLength-1。因此在判断队列是否将要满的时候需要用到:
if ((theBack + 1) % arrayLength == theFront)
arrayLength是队列数组的长度
theBack是数组的尾的位置,theFront是数组头的前一个位置
具体看下图
理解了这个,再来看数组描述的队列:
class arrayQueue:public queue<T>
{
private:
int theFront;//队首
int theBack;//队尾
int arrayLength;//数组长度
T *queue;
public:
arrayQueue(int initialCapacity=10)//构造函数
{
theBack=0;
theFront=0;
arrayLength=initialCapacity;
queue=new T[arrayLength];
}
bool empty()const
{
if(theBack==theFront)
return true;
return false;
}
int size()const
{
return (theBack-theFront+arrayLength)%arrayLength;
}
T& front()
{
if(theBack==theFront)
//抛出异常,队列为空
int tmp=(theFront+1)%arrayLength;
return queue[tmp];
}
T& back()
{
if(theBack==theFront)
//抛出异常,队列为空
return queue[theBack];
}
void pop()
{
if(theBack==theFront)
//抛出异常,队列为空
theFront=(theFront+1)%arrayLength;//更新theFront的值
queue[theFront].~T(); //在数组上调用一个Template模板的析构函数
}
void push(const T& theElement);
};
void arrayQueue<T>::push(const T& theElement)
{
if((theBack + 1) % arrayLength == theFront)//如果队列将要满
//增加数组长度
theBack=(theBack+1)%arrayLength;
queue[theBack]=theElement;
}