王道数据结构源码实战自学-循环队列(c++版)
1 循环队列知识点概述
经常会考的一个知识点是循环队列
下图中,一个循环队列的大小是 6 ,但是有6个位置只能存5个元素。
front指向对头,rear指向队尾,认为 front = rear 的时候队列为空。当rear+1=front时,认为队列满了,这也是为什么有6个位置只能放5个元素。
出队、入队的时候rear永远指向下一个位置,front指向第一个元素的位置
- 判断是否满了的情况时会用到(Q.rear + 1) % MaxSize,为什么要加一再除以MaxSize取余。因为在下图的情况里
MaxSize = 6
不使用加一取余
rear+1=6
front=0
两个值不等,但是实际情况是列表满了
使用加一取余
(rear+1)% MaxSize=6 % 6 = 0
front = 0
两个值相等,列表已满
出队或者入队以后,给 rear+1 也是 rear = (rear+1) % MaxSize ; 为什么呢?如下图的情况里
以入队为例:现在列表还没有满,如果再插入一个元素,rear应该指向的位置是哪里?
直接加一
rear + 1 = 6
但是根本不存在6
加一取余
(rear + 1) % MaxSize = 6 % 6 = 0
2 循环队列代码实现
实现的是数组形式的,链表实现的循环链表考研中出现几率较少
#include <iostream>
using namespace std;
#define MaxSize 5
typedef int ElemType;
typedef struct {
ElemType data[MaxSize];//数组,只能存放MaxSize-1个元素
int front, rear;//队列头 队列尾
}SqQueue;
2.1 初始化函数
初始化就是将对头和队尾都置为0,即队列为空
//初始化
void InitQueue(SqQueue& Q) {
Q.front = Q.rear = 0;
}
2.2 判空函数
判空的条件就是 front= rear
注意:这里判空没必要front等于rear等于0,因为有可能在不断地入队出队的过程中,front和rear位置一点点变化,最终导致队列为空的时候front=rear,但是等于3或者其他数字。所以没必要要求为0,只要相等即可判断为 空队列
//判空
bool isEmpty(SqQueue Q) {
if (Q.front == Q.rear) {
return true;
}
return false;
}
2.3 入队
首先判断队列是否为空
将入队的值直接赋值给rear所指的位置
//入队
bool EnQueue(SqQueue& Q, ElemType x) {
if ((Q.rear + 1) % MaxSize == Q.front) {
return false;//判断队列满了
}
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MaxSize;//向后移动一格
return true;
}
int main()
{
SqQueue Q;
//初始化
InitQueue(Q);
//判空
bool empt = false;
empt = isEmpty(Q);
if (empt)
{
cout << "Queue is empty" << endl;
}
//入队
bool ret = false;
EnQueue(Q, 3);
EnQueue(Q, 4);
EnQueue(Q, 5);
ret = EnQueue(Q, 6);
if (ret)
{
cout << "success" << endl;
}
else
{
cout << "false" << endl;
}
ret = EnQueue(Q, 7);
if (ret)
{
cout << "success" << endl;
}
else
{
cout << "false" << endl;
}
}
2.4 出队
先判断队列是否为空
注意的事项是front+1的时候要加一取余
//出队
bool DeQueue(SqQueue& Q, ElemType& x) {
if (Q.rear == Q.front) {
return false;//队列为空
}
x = Q.data[Q.front];//将第一个元素(出队元素)赋值给x
Q.front = (Q.front + 1) % MaxSize;
return true;
}
int main()
{
SqQueue Q;
//初始化
InitQueue(Q);
//判空
bool empt = false;
empt = isEmpty(Q);
if (empt)
{
cout << "Queue is empty" << endl;
}
//入队
bool ret = false;
EnQueue(Q, 3);
EnQueue(Q, 4);
EnQueue(Q, 5);
ret = EnQueue(Q, 6);
if (ret)
{
cout << "success" << endl;
}
else
{
cout << "false" << endl;
}
ret = EnQueue(Q, 7);
if (ret)
{
cout << "success" << endl;
}
else
{
cout << "false" << endl;
}
//出队测试
ElemType m;
bool de = false;
de = DeQueue(Q, m);
if (de)
{
cout << "出队成功,值为: " << m << endl;
}
else
{
cout << "出队失败" << endl;
}
}