C++ 循环队列

来源:互联网 发布:孙尚香 知乎 编辑:程序博客网 时间:2024/06/06 11:38

出处:http://hi.baidu.com/qq0400/item/06b51ed6c780385ad63aae8f

循环队列
     为充分利用向量空间,克服"假上溢"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。


(1) 循环队列的基本操作
     循环队列中进行出队、入队操作时,头尾指针仍要加1,朝前移动。只不过当头尾指针指向向量上界(QueueSize-1)时,其加1操作的结果是指向向量的下界0。这种循环意义下的加1操作可以描述为:
① 方法一:
    if(i+1==QueueSize) //i表示front或rear
        i=0;
    else
        i++;

② 方法二--利用"模运算"
    i=(i+1)%QueueSize;

(2) 循环队列边界条件处理
     循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。 【参见动画演示】
     解决这个问题的方法至少有三种:
  ① 另设一布尔变量以区别队列的空和满;
  ② 少用一个元素的空间。约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队满(注意:rear所指的单元始终为空);
  ③使用一个计数器记录队列中元素的总数(即队列长度)。

代码实现:

#include <iostream>
using namespace std;

template <typename T>
class SqQueue
{
public:
  SqQueue(int init = 10);
  bool SqQueueEmpty() const;//判断队列是否为空
  void SqQueueTraverse() const;//遍历循环队列
  int SqQueueLength() const;//返回队列中元素个数

  bool EnSqQueue(T e);
  bool DelSqQueue();

private:
  int size;//允许的最大存储空间,以元素为单位
  int front;//队列头指针
  int rear;//队列尾指针
  T *base;//存储空间基址
};

template <typename T>
SqQueue<T>::SqQueue(int init)
{
  size = init;//初始大小
  base = new T[size];
  if(!base)exit(1);//存储分配失败
  front = rear = 0;//空栈中元素个数
}

//返回队列Q中元素个数,即队列长度
template <typename T>
int SqQueue<T>::SqQueueLength() const
{
  return ((rear-front+size)%size);
}

template <typename T>
void SqQueue<T>::SqQueueTraverse() const
{
  int length = (rear-front+size)%size;
  cout<<"从队尾到队首为:"<<endl;
  while(length--)
  {
    cout<<base[front+length]<<" ";
  }
  cout<<endl;
}

//若当前队列不满,插在当前队列的元素之后
//插入元素e为新的队列尾元素,并返回true,否则返回false。
template <typename T>
bool SqQueue<T>::EnSqQueue(T e)
{
  if((rear+1)%size==front)
  {//队列满
   cout<<"队列已满!"<<endl;
    return false;
  }
  else
  {
    base[rear] = e;
    rear = (rear+1)%size;
    return true;
  }
}

template <typename T>
bool SqQueue<T>::DelSqQueue()
{//队列空
  if(front==rear)
  {
    return false;
  }
  front = (front+1)%size;
  return true;
}

int main()
{
  SqQueue<int> *sq = new SqQueue<int>;
  int input;
  cout<<"请输入要插入元素(Ctrl+D停止输入):"<<endl;
  while(cin>>input)
  {
    sq->EnSqQueue(input);
  }
 /* sq->EnSqQueue(2);
  sq->EnSqQueue(3);
  sq->EnSqQueue(4);
  sq->EnSqQueue(5);
  sq->EnSqQueue(6);
  */

  cout<<"队列长度为:"<<sq->SqQueueLength()<<endl;
  sq->SqQueueTraverse();
 
  cout<<"删除对象后"<<endl;
  sq->DelSqQueue();
  cout<<"队列长度为:"<<sq->SqQueueLength()<<endl;
  sq->SqQueueTraverse();
  return 0;

}