声明:本文为学习数据结构与算法分析(第三版) Clifford A.Shaffer 著的学习笔记,代码有参考该书的示例代码。
队列
队列是一种受限制的线性表。
队列元素只能从队尾插入(称为入队 ,enqueue),只能从队首删除(称为出队,dequeue)。由于队列的特性,队列被称为“FIFO”线性表(先进先出)
队列的实现可以有两种方式,即顺序队列和链式队列。
队列的ADT如下:
template<typename E>
class Queue
{
Queue(const Queue&) {}
Queue& operator= (const Queue&) {}
public:
Queue() {}
virtual ~Queue() {}
virtual void clear() = 0;
virtual void enqueue(const E&) = 0;
virtual E dequeue() = 0;
virtual const E& front() const = 0;
virtual int length() const = 0;
};
顺序队列
对顺序队列的实现可以假定数组是循环的。
对于长度为 n 的数组,数组满时需要存放 n 个元素,那如何判断数组满和空时的状态?
假设定义,当数组空时,rear 比 front 小 1 。
这时候,如果 front 在 0 的位置,并且数组满,则简单计算就知道 rear 在 n-1 的位置。从循环队列的角度来看,rear 比front 小 1 。
然而事实上,因为存放 n 个元素的队列有 n+1 种状态,但是长度为 n 的数组只有 n 种状态,不管如何定义队列状态,都不能解决上述问题。
解决这个问题有两种方法:
- 额外记录数组的长度,或者使用一个布尔变量来标记区分。
- 定义数组长度为 n+1 .
本文的实现就是采用第二种方法。
当 rear = front 时,队列为空;
当 rear = front-1 时,队列为满;
当然,这取决于如何定义。课本的定义与我的稍稍不同(rear = front-1时队列空)
链式队列
用链表实现队列简单一点,只需要两个指针记录即可(front 和 rear)。
如果为了操作简单一点,实现一个头结点也是可以的。
实现代码可在我的github上找到:
xiaosa233的github