基于数组的循环队列(C++模板实现)

转自: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;
}
比较简单,细节不再赘述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值