队列
队列(queue)是一种限定存取位置的线性表。它只允许在表的一端插入,在另一端删除。允许插入的一端叫做队尾(rear),允许删除的一端叫做队头(front)。队列所具有的这种特性叫做先进先出FIFO(First In/First Out)。
先定义队列的抽象数据类型:
template<class T>
class Queue
{
public:
Queue() {};
~Queue() {};
//往队列中加入元素
virtual void EnQueue(const T& x) = 0;
//取出队头元素
virtual bool DeQueue(T& x) = 0;
//读取队头元素的值
virtual bool getFront(T& x) = 0;
//判断队列是否为空
virtual bool IsEmpty()const = 0;
//判断队列是否为满
virtual bool IsFull()const = 0;
//返回队列中元素个数
virtual int getSize()const = 0;
};
循环队列
循环队列是基于数组的存储表示。
循环队列的类定义
template<class T>
class SeqQueue : public Queue<T>
{
public:
SeqQueue(int sz = 10);
~SeqQueue() { delete[] elements; }
//若队列不满 则将x入队 否则进行对溢出处理
void EnQueue(const T& x);
//若队列不为空 则函数返回true及队头元素并将队头元素出队 否则返回false
bool DeQueue(T& x);
//若队列不为空 则函数返回true及队列头元素的值 否则返回false
bool getFront(T& x);
//判断队列是否为空
bool IsEmpty()const;
//判断队列是否已满
bool IsFull()const;
//返回队列中元素个数
int getSize()const;
protected:
int front; //队尾指针
int rear; //队头指针
T* elements; //存储队列的数组
int maxSize; //最大可容纳元素个数
};
特别需要注意,若elements中存储了maxSize个元素,则判断队列是否为空和是否为满的依据都是rear是否与front相等,会带来不必要的操作。因此在实现时elements可以值使用maxSize-1个元素,队尾不存储元素,此时判断队列是否为空的操作仍是front == rear,但是判断是否为满的条件变为了 (rear + 1) % maxSize == front。
构造函数
template<class T>
SeqQueue<T>::SeqQueue(int sz) : front(0), rear(0), maxSize(sz)
{
elements = new T[maxSize]; //创建队列空间
assert(elements != NULL);
}
入队操作
template<class T>
bool SeqQueue<T>::EnQueue(const T& x)
{
if (IsFull()) return false;
elements[rear] = x;
rear = (rear + 1) % maxSize;
return true;
}
取队头元素和出队操作
取队头元素
template<class T>
bool SeqQueue<T>::getFront(T& x)
{
if (IsEmpty()) return false;
x = elements[front];
return true;
}
出队操作
template<class T>
bool SeqQueue<T>::DeQueue(T& x)
{
if (IsEmpty()) return false;
x = elements[front];
front = (front + 1) % maxSize;
return true;
}
判断队列是否为空和是否为满
template<class T>
bool SeqQueue<T>::IsEmpty()const
{
return front == rear;
}
template<class T>
bool SeqQueue<T>::IsFull()const
{
return (rear + 1) % maxSize == front;
}
返回队列中元素个数
template<class T>
int SeqQueue<T>::getSize()const
{
return (rear - front + maxSize) % maxSize;
}
循环队列的基本操作定义完毕。