0.概述
本文首先以思维导图介绍队列的基本知识,其次给出循环队列(顺序存储结构)首尾不同指针指向不同位置时,队列的判空和判满条件,最后给出三种不同指针指向的循环队列代码实现!链式队列实现,请参考我的另一篇博客:队列——链式存储结构实现.
2.不同指针指向,队列判空/判满条件
1.
rear:指向队尾元素 front:指向队头元素前一个位置
(1)牺牲一个存储空间
(2)判空条件:front == rear
(3)判满条件:(rear+1)%MaxSize == front
2.
rear:指向队尾下一个元素 front:指向队头元素
(1)牺牲一个存储空间
(2)判空条件:front == rear
(3)判满条件:(rear+1)%MaxSize == front
3.
rear:指向队尾元素 front:指向队头元素 ——注意判空和判满条件
(1)牺牲一个存储空间
(2)判空条件:(rear+1)%MaxSize == front
(3)判满条件:(rear+2)%MaxSize == front
区别与联系
(1)上述三种指针指向的判空/判满条件均是牺牲一个存储空间,上述三种需要特别注意第三种的指针指向(可以通过画一个换装图好好体会)。
(2)均可以在结构体内增加tag
(标记上一步是入队还是出队操作,只有入队才会造成假溢出现象) 或size
(标记循环队列中存储数据元素的个数,以此用来区分队满和队空)
(3)基本入队、出队操作略有不同(具体见代码)
3.循环队列代码实现
1. rear:指向队尾元素 front:指向队头元素前一个位置
#include
using namespace std;
//rear:指向队尾元素 front:指向队头元素前一个位置
#define MaxSize 3
typedef struct{
int data[MaxSize];
int front; //队头指针
int rear; //队尾指针
}CriQueue;
//0.初始化
void InitQueue(CriQueue &Q){
//牺牲一个存储空间
//rear:指向队尾元素 front:指向队头元素前一个位置
//判空条件:front==rear
//判满条件:(rear+1)%MaxSize==front
Q.front=0;
Q.rear=0;
}
//1.入队操作
bool EnQueue(CriQueue &Q,int x){
if((Q.rear+1)%MaxSize==Q.front){ // 判断队列是否满
cout<<"队列已满!"<<endl;
return false;
}
Q.rear=(Q.rear+1)%MaxSize; // 向下一个存储单元移动
Q.data[Q.rear]=x; //存值
return true;
}
//2.出队操作
bool DeQueue(CriQueue &Q,int &x){
if(Q.front==Q.rear){ // 判断队列是否为空
cout<<"队列为空!"<<endl;
return false;
}
x=Q.data[Q.front+1]; //取值
Q.front=(Q.front+1)%MaxSize; // 向下一个存储单元移动
return true;
}
//3.获取队头元素
bool GetHead(CriQueue &Q,int &x){
if(Q.front==Q.rear){ // 判断队列是否为空
cout<<"队列为空!"<<endl;
return false;
}
x=Q.data[Q.front+1];
return true;
}
//主程序
int main(){
CriQueue Q;
InitQueue(Q);
int x;
//1.入队 获取队头
if(EnQueue(Q,8)){
if(GetHead(Q,x)){
cout<<"队头元素:"<<x<<endl;
}
}
EnQueue(Q,9);
EnQueue(Q,10);
//2.出队
if(DeQueue(Q,x)){
cout<<"出队元素:"<<x<<endl;
}
if(GetHead(Q,x)){
cout<<"队头元素:"<<x<<endl;
}
return 0;
}
2. rear:指向队尾下一个元素 front:指向队头元素
#include
using namespace std;
//rear:指向队尾下一个元素 front:指向队头元素
#define MaxSize 3
typedef struct{
int data[MaxSize];
int front; //队头指针
int rear; //队尾指针
}CriQueue;
//0.初始化
void InitQueue(CriQueue &Q){
//牺牲一个存储空间
//rear:指向队尾下一个元素 front:指向队头元素
//判空条件:front==rear
//判满条件:(rear+1)%MaxSize==front
Q.front=0;
Q.rear=0;
}
//1.入队操作
bool EnQueue(CriQueue &Q,int x){
if((Q.rear+1)%MaxSize==Q.front){ // 判断队列是否满
cout<<"队列已满!"<<endl;
return false;
}
Q.data[Q.rear]=x; //存值
Q.rear=(Q.rear+1)%MaxSize; // 向下一个存储单元移动
return true;
}
//2.出队操作
bool DeQueue(CriQueue &Q,int &x){
if(Q.front==Q.rear){ // 判断队列是否为空
cout<<"队列为空!"<<endl;
return false;
}
x=Q.data[Q.front]; //取值
Q.front=(Q.front+1)%MaxSize; // 向下一个存储单元移动
return true;
}
//3.获取队头元素
bool GetHead(CriQueue &Q,int &x){
if(Q.front==Q.rear){ // 判断队列是否为空
cout<<"队列为空!"<<endl;
return false;
}
x=Q.data[Q.front];
return true;
}
//主程序
int main(){
CriQueue Q;
InitQueue(Q);
int x;
//1.入队 获取队头
if(EnQueue(Q,8)){
if(GetHead(Q,x)){
cout<<"队头元素:"<<x<<endl;
}
}
EnQueue(Q,9);
EnQueue(Q,10);
//2.出队
if(DeQueue(Q,x)){
cout<<"出队元素:"<<x<<endl;
}
if(GetHead(Q,x)){
cout<<"队头元素:"<<x<<endl;
}
return 0;
}
3.rear:指向队尾元素 front:指向队头元素 ——注意判空和判满条件
#include
using namespace std;
//rear:指向队尾元素 front:指向队头元素 ——注意判空和判满条件
#define MaxSize 3
typedef struct{
int data[MaxSize];
int front; //队头指针
int rear; //队尾指针
}CriQueue;
//0.初始化
void InitQueue(CriQueue &Q){
//牺牲一个存储空间
//rear:指向队尾元素 front:指向队头元素
//判空条件:(rear+1)%MaxSize==front
//判满条件:(rear+2)%MaxSize==front
Q.front=0;
Q.rear=MaxSize-1;
}
//1.入队操作
bool EnQueue(CriQueue &Q,int x){
if((Q.rear+2)%MaxSize==Q.front){ // 判断队列是否满
cout<<"队列已满!"<<endl;
return false;
}
Q.rear=(Q.rear+1)%MaxSize; // 向下一个存储单元移动
Q.data[Q.rear]=x; //存值
return true;
}
//2.出队操作
bool DeQueue(CriQueue &Q,int &x){
if((Q.rear+1)%MaxSize==Q.front){ // 判断队列是否为空
cout<<"队列为空!"<<endl;
return false;
}
x=Q.data[Q.front]; //取值
Q.front=(Q.front+1)%MaxSize; // 向下一个存储单元移动
return true;
}
//3.获取队头元素
bool GetHead(CriQueue &Q,int &x){
if((Q.rear+1)%MaxSize==Q.front){ // 判断队列是否为空
cout<<"队列为空!"<<endl;
return false;
}
x=Q.data[Q.front];
return true;
}
//主程序
int main(){
CriQueue Q;
InitQueue(Q);
int x;
//1.入队 获取队头
if(EnQueue(Q,8)){
if(GetHead(Q,x)){
cout<<"队头元素:"<<x<<endl;
}
}
EnQueue(Q,9);
EnQueue(Q,10);
//2.出队
if(DeQueue(Q,x)){
cout<<"出队元素:"<<x<<endl;
}
if(GetHead(Q,x)){
cout<<"队头元素:"<<x<<endl;
}
return 0;
}