转自:http://blog.sina.com.cn/s/blog_8689e44d0100su2a.html
循环队列使用数组实现的话,简单、方便。之前实现的队列,当尾端索引到达队列最后的时候,无论前面是否还有空间,都不能再添加数据了。循环队列使得队列的存储单元可以循环利用,它需要一个额外的存储单元来判断队列是否已满。
头文件如下:
#ifndef CIRCULARQUEUE_HPP_
#define CIRCULARQUEUE_HPP_
#include <cstddef>
#include <iostream>
// CircularQueue类模板实现了循环队列
template <typename DataType>
class CircularQueue
{
public:
// 环状队列,首尾相接,相关操作的实现需要空出一个存储单元
// nMaxSize[IN]:最多可以存储的元素个数
explicit CircularQueue(int nMaxSize)
{
// 最少存储一个元素,还需要一个空单元
m_nQSize = (nMaxSize <= 0) ? 2 : nMaxSize+1;
m_pQueue = new DataType[m_nQSize];
// 初始状态,用第一个存储单元作为那个空单元
m_nFront = m_nRear = 0;
}
~CircularQueue()
{
delete[] m_pQueue;
}
// 获取最大容量
int getMaxSize() const
{
return m_nQSize-1;
}
// 将d加入队列
// d[IN]:要添加的数据
// 返回值:true-成功,false-失败
bool add(const DataType & d)
{
if (isCannotAdd()) // 队列已满
{
return false;
}
m_nRear = cacNewIdx(m_nRear);
m_pQueue[m_nRear] = d;
return true;
}
// 移除一个元素
// d[OUT]:被移除的元素的拷贝
// 返回值:true-成功,false-失败
bool del(DataType * d=NULL)
{
if (isEmpty()) // 队列为空
{
return false;
}
m_nFront = cacNewIdx(m_nFront);
if (d != NULL)
{
*d = m_pQueue[m_nFront];
}
return true;
}
// 清空队列
void delAll()
{
m_nFront = m_nRear = 0;
}
// 判断队列是否为空
bool isEmpty() const
{
return m_nFront == m_nRear;
}
// 判断是否不能再添加元素
bool isCannotAdd() const
{
return cacNewIdx(m_nRear) == m_nFront;
}
// for debug
void dump() const
{
using std::cout;
using std::endl;
cout << "from front to rear: ";
if (isEmpty())
{
cout << endl;
return;
}
for (int i=cacNewIdx(m_nFront); i!=m_nRear; i=cacNewIdx(i))
{
cout << m_pQueue[i] << ",";
}
cout << m_pQueue[m_nRear] << endl;
}
private:
// 计算新索引
// 这是“循环”的核心
int cacNewIdx(int nIdx) const
{
return (nIdx+1) % m_nQSize;
}
private:
CircularQueue();
CircularQueue(const CircularQueue &);
CircularQueue & operator=(const CircularQueue &);
private:
int m_nQSize; // 队列的存储单元个数
DataType * m_pQueue; // 存储元素的数组
int m_nFront; // 前端(输出端)索引
int m_nRear; // 后端(输入端)索引
};
#endif // CIRCULARQUEUE_HPP_
循环队列,所有存储单元形成一个环,所以存储单元个数肯定是有限的,需要一个上限。我这里没有实现拷贝构造函数和赋值操作符。
测试文件如下:
#include "CircularQueue.hpp"
#include <cstdlib>
int main()
{
using std::cout;
using std::endl;
cout << "CircularQueue<int> qc(5):" << endl;
CircularQueue<int> qc(5);
qc.del();
qc.add(1);
qc.add(2);
qc.add(3);
qc.add(4);
qc.add(5);
qc.add(6);
qc.dump();
qc.del();
qc.del();
qc.dump();
qc.add(7);
qc.add(8);
qc.add(9);
qc.dump();
qc.delAll();
qc.dump();
system("pause");
return 0;
}
比较简单,细节不再赘述。