在前两篇中讲述了顺序队列中的队头移动与不移动两种顺序队列,今天讨论顺序队列中的循环队列,这种循环队列是用一维数组实现的。在队头移动的情况下,根据元素个数与队列容量之间的数量关系来解决假溢出问题。
从上图中我们可以理解为什么这种队列结构可以解决假溢出问题,但是随之而来,我们要如何判定循环队列已满呢?
在此处我有三种办法:
其一,牺牲一个存储单元,使得一旦插入时发现元素个数已经达到最大元素个数-1,便说明已满。
其二,设置一个标记,若已插入元素,设置为1,为插入元素,设置为0,在插入时,判断标记的值。如下图示。
其三,使用一个计数器count,每次将要插入时,count++,判断count与最大元素个数的大小,相等,表示已满
在本文中,我使用第一种方法,以牺牲一个存储单元来解决队列已满问题。
//循环队列
#include<iostream>
using namespace std;
typedef int typedata;
#define max_size 5
typedef class Seqlist{
public:
Seqlist()
:front(0),
rear(0)
{}
//返回元素个数
int Size()
{
if (rear >= front)
return rear - front;
else
{
return max_size - (front - rear);
}
}
//入队列
bool push_back(typedata data)
{
if (Size() == (max_size-1))
{
cout << "队列已满" << endl;
return false;
}
else if (rear == (max_size-1))
{
array[rear++] = data;
rear = 0;
}
else
array[rear++] = data;
return true;
}
//出队列,队头
bool pop_front()
{
if (Size() == 0)
{
cout << "队列已空" << endl;
return false;
}
if (front == max_size)
{
front = 0;
return true;
}
else
front++;
return true;
}
//打印
void 打印()
{
int i = front;
if (front < rear)
{
for (i = front; i < rear; ++i)
cout << array[i] << " ";
cout << endl << endl;
}
else
{
for (i = front; i < max_size; ++i)
cout << array[i] << " ";
for (i = 0; i < rear; ++i)
cout << array[i] << " ";
cout << endl << endl;
}
}
~Seqlist()
{
rear = 0;
front = 0;
}
private:
typedata array[max_size];
int front;
int rear;
};
void test()
{
Seqlist p;
p.push_back(1);
p.push_back(2);
p.push_back(3);
p.push_back(4);
p.push_back(5);
cout << p.Size() << endl;
p.打印();
p.pop_front();
cout << p.Size() << endl;
p.打印();
p.push_back(4);
p.push_back(5);
p.push_back(6);
p.push_back(7);
cout << p.Size() << endl;
p.打印();
}
int main()
{
test();
return 0;
}