如何实现循环队列
在队列的顺序存储中,除了使用一组地址连续的单元依次存放从队列头到队列尾的元素外,还需要另外设置front和rear两个指针,分别指示队列头元素以及队列尾元素的位置。初始化建空队列时,令front=rear=0
,每当出入新的队列尾元素时,尾指针增1;而每当删除队列头元素时,则执行头指针增1
为充分利用内存空间,克服“假溢出”现象的方法是:将内存空间想象为一个首尾相接的圆环,存储在其中的队列称为循环队列。循环队列中,由于入队时尾指针向前追赶尾指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear
来判别队列是空还是满
解决这个问题的方法至少有两种:
- 另外设置一个标志位来区别队列是空还是满
- 少用一个元素空间,约定以队列头指针在队列尾指针的下一个位置时,作为队列满状态的标志。队满时
(rear + 1) % MAXSIZE = front
#define MAXSIZE 1000
typedef int ElemType;
struct CirSeqQueue
{
ElemType data[MAXSIZE];
int front;
int rear;
}
//循环队列初始化
void QueueInitial(CirSeqQueue* pQ)
{
pQ->front = pQ->rear = 0;
}
//循环队列判空
bool IsEmpty(CirSeqQueue* pQ)
{
return pQ->front == pQ->rear;
}
//循环队列判满
bool isFull(CirSeqQueue* pQ)
{
return (pQ->rear + 1) % MAXSIZE == pQ->front;
}
//元素进队列
void EnQueue(CirSeqQueue* pQ, ElemType e)
{
if (isFull(pQ))
{
cout << "队列溢出!" << endl;
exit(1);
}
pQ->rear = (pQ->rear + 1) % MAXSIZE;
pQ->data[pQ->rear] = e;
}
//元素出队列
ElemType DeQueue(CirSeqQueue* pQ)
{
if (IsEmpty(pQ))
{
cout << "空队列!" << endl;
exit(1);
}
pQ->front = (pQ->front + 1) % MAXSIZE;
return pQ->data[pQ->front];
}
//取队头元素
ElemType GetFront(CirSeqQueue* pQ)
{
if (IsEmpty(pQ))
{
cout << "空队列!" << endl;
exit(1);
}
return pQ->data[(pQ->front + 1) % MAXSIZE];
}
//循环队列置空
void MakeEmpty(CirSeqQueue* pQ)
{
pQ->front = pQ->rear = 0;
}