循环队列就是将队列存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间,供队列循环使用。在循环队列结构中,当存储空间的最后一个位置已被使用而再要进入队运算时,只需要存储空间的第一个位置空闲,便可将元素加入到第一个位置,就是将存储空间的第一个位置作为队尾。 循环队列可以更简单防止伪溢出的发生,但队列大小是固定的。
在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件是front=rear,而队列判满的条件是front=(rear+1)%MaxSize
Attention:数据结构专栏从此篇开始难度增加,对指针与对象的构造全部在堆区进行,代码可读性会有所降低。若不习惯,还可阅读笔者往期的数据结构专栏
下面是正文:
一个Quene对象包括一个int 类型指针base,两个int 变量front 和rear。empty是一个队列是否为空的检测函数。提前定义好maxsize 为10
#include <iostream>
using namespace std;
#define maxsize 10
struct Quene {
int* base; // 初始化的动态分配存储空间
int front; // 头指针,若队列不空,指向队列头元素
int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
};
bool empty(Quene*tmp) {
return tmp->front == tmp->rear;
}
SeqQueue() ——队列创建函数
- 在栈区创建一个Quene类型指针q,指向堆区创建的Quene的一个实例化对象
- 实例化对象中的base指针指向一个堆区创建的int类型数组对象
- 将实例化对象中的front和rear置为0
Quene* SeqQueue() {//用于构造新队列
Quene* q = new Quene();//q指向堆区的quene实例对象
q->base = new int[maxsize];//base指针指向数组
q->front = q->rear = 0;//front和rear都置为0
cout << "新队列已构造" << endl;
return q;//返回一个q指针
}
EnQuene() ——入队函数
- 先判断队列是否满队,不满则函数继续执行
- rear指针+1
- 将参数赋给rear指向的数组下标
void EnQueue(Quene* tmp,int x) {
if ((tmp->rear + 1) % maxsize == tmp->front) {//若rear+1后与front相同就返回
cout << "队列已满,无法入队" << endl;
return;
}
tmp->rear = (tmp->rear + 1) % maxsize;//尾指针+1
tmp->base[tmp->rear] = x;//参数值赋给rear所在下标
cout << x << " 入队" << endl;
}
DeQuene()——出队函数
- 先判断队列是否为空,不为空则函数继续执行
- front指针+1
- 输出front指向的数组下标元素
int DeQueue(Quene* tmp) {
if (empty(tmp)) {//判断是否空队,空队则返回
cout<<"队列为空,无数据" << endl;
return 0;
}
tmp->front = (tmp->front + 1) % maxsize;//front指针+1
cout << tmp->base[tmp->front]<<" 出队" << endl;
return tmp->base[tmp->front];
}
getHead()——头元素访问函数
- 先判断队列是否为空,非空则函数继续执行
- 访问front指针+1后指向的数组下标(过程不改变front的值)
int getHead(Quene* tmp) {
if (empty(tmp)) {//空队判断
cout << "队列为空,无数据" << endl;
return 0;
}
cout << "队列首元素为 " << tmp->base[(tmp->front + 1) % maxsize] << endl;
return tmp->base[(tmp->front + 1) % maxsize];//返回front指针+1后的下标元素值
}
PrintQuene()——队列打印函数
- 创建一个临时变量p来充当数组指针
- while循环,当p不等于rear时执行
- p先+1
- 打印p所指的数组下标元素
void PrintQuene(Quene*tmp) {
int p = tmp->front;//创建一个变量p接收front指针值
cout << "队列中元素为:";
while (tmp->rear != p) {//循环条件:p不等于rear指针
p = (p + 1) % maxsize;//指针p+1
cout<< tmp->base[p] << " ";//打印p指向的数组下标
}
cout << endl;
}
一段测试用代码
void test() {
Quene* q1=SeqQueue();
EnQueue(q1,4);
EnQueue(q1,8);
getHead(q1);
DeQueue(q1);
EnQueue(q1,31);
EnQueue(q1,40);
DeQueue(q1);
DeQueue(q1);
getHead(q1);
EnQueue(q1,89);
EnQueue(q1,67);
PrintQuene(q1);
}
int main() {
test();
}