顺序队列中包含了队头指针和队尾指针,按照队尾指针所指向的位置的不同,可将顺序队列分成了如下两种:
一、队尾指针指向队尾元素的后一个位置:
在针对队列的基本操作中,如何判空和判满?有以下三种办法
(1)牺牲掉一个存储空间:
#include<stdio.h>
#include<stdlib.h>
//顺序队列的数据类型定义
#define ElemType int
#define MaxSize 15
typedef struct{
ElemType data[MaxSize];
int front,rear;
}SqQueue;
//初始化顺序队列Q:
void InitQueue(SqQueue &Q)
{
Q.front=0;
Q.rear=0;
}
//判空操作:
bool QueueEmpty(SqQueue Q)
{
if(Q.front==Q.rear)return true;
else return false;
}
//入队操作:
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;
printf("\n此队列中目前有: %d个元素\n",(Q.rear+MaxSize-Q.front)%MaxSize);
return true;
}
//出队操作:
bool DeQueue(SqQueue &Q,ElemType &x)
{
if(Q.front==Q.rear)return false;
printf("\n此队列中目前有: %d个元素\n",(Q.rear+MaxSize-Q.front)%MaxSize);
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return true;
}
//获得队头元素的值:
bool GetTop(SqQueue Q,ElemType &x)
{
if(Q.front==Q.rear)return false;
x=Q.data[Q.front];
printf("\n此队列中目前有: %d个元素\n",(Q.rear+MaxSize-Q.front)%MaxSize);
return true;
}
//主函数
int main()
{
int x;
SqQueue Q; //声明一个顺序队列Q
InitQueue(Q); //初始化顺序队列Q
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n向队列中输入元素:\n");
while(1)
{
scanf("%d",&x);
if(x==9999)
{
printf("\n输入结束\n");
break;
}
if(EnQueue(Q,x))printf("\n成功入队\n");
else{
printf("\n队列已满\n");
break;
}
}
if(GetTop(Q,x))printf("\n队头元素为: %d\n",x);
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n依次出队:\n");
while(DeQueue(Q,x))
{
printf("%d ",x);
}
printf("\n");
return 0;
}
我特地在基本操作函数中加了个输出语句,用来输出当前顺序队列中元素的个数。
(2)在队列的数据类型定义中设置一个新的成员size,用来保存当前队列内的元素个数,这个size随着入队和出队操作而发生变化:(这样就保证了每个存储空间都被利用)
#include<stdio.h>
#include<stdlib.h>
//顺序队列的数据类型定义
#define ElemType int
#define MaxSize 15
typedef struct{
ElemType data[MaxSize];
int front,rear;
int size;
}SqQueue;
//初始化顺序队列Q:
void InitQueue(SqQueue &Q)
{
Q.front=0;
Q.rear=0;
Q.size=0;
}
//判空操作:
bool QueueEmpty(SqQueue Q)
{
if(Q.size==0)return true;
else return false;
}
//入队操作:
bool EnQueue(SqQueue &Q,ElemType x)
{
if(Q.size==MaxSize)return false;
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%MaxSize;
Q.size++;
printf("\n此队列中目前有: %d个元素\n",Q.size);
return true;
}
//出队操作:
bool DeQueue(SqQueue &Q,ElemType &x)
{
if(Q.size==0)return false;
printf("\n此队列中目前有: %d个元素\n",Q.size);
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
Q.size--;
return true;
}
//获得队头元素的值:
bool GetTop(SqQueue Q,ElemType &x)
{
if(Q.size==0)return false;
x=Q.data[Q.front];
printf("\n此队列中目前有: %d个元素\n",Q.size);
return true;
}
//主函数
int main()
{
int x;
SqQueue Q; //声明一个顺序队列Q
InitQueue(Q); //初始化顺序队列Q
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n向队列中输入元素:\n");
while(1)
{
scanf("%d",&x);
if(x==9999)
{
printf("\n输入结束\n");
break;
}
if(EnQueue(Q,x))printf("\n成功入队\n");
else{
printf("\n队列已满\n");
break;
}
}
if(GetTop(Q,x))printf("\n队头元素为: %d\n",x);
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n依次出队:\n");
while(DeQueue(Q,x))
{
printf("%d ",x);
}
printf("\n");
return 0;
}
(3)在队列的数据类型定义中增加一个成员tag,tag为0表示之前进行了删除操作,为1表示之前进行了插入操作,当队头指针和队尾指针相同时,如果tag=0表示队空,tag=1则表示队满:
#include<stdio.h>
#include<stdlib.h>
//顺序队列的数据类型定义
#define ElemType int
#define MaxSize 15
typedef struct{
ElemType data[MaxSize];
int front,rear;
int tag;
}SqQueue;
//统计当前队列中元素个数:
int QueueElemNumber(SqQueue &Q)
{
if(Q.tag==1&&Q.rear==Q.front)return MaxSize;
else return (Q.rear+MaxSize-Q.front)%MaxSize;
}
//初始化顺序队列Q:
void InitQueue(SqQueue &Q)
{
Q.front=0;
Q.rear=0;
Q.tag=0;
}
//判空操作:
bool QueueEmpty(SqQueue Q)
{
if(Q.front==Q.rear&&Q.tag==0)return true;
else return false;
}
//入队操作:
bool EnQueue(SqQueue &Q,ElemType x)
{
if(Q.front==Q.rear&&Q.tag==1)return false;
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%MaxSize;
Q.tag=1;
printf("\n此队列中目前有: %d个元素\n",QueueElemNumber(Q));
return true;
}
//出队操作:
bool DeQueue(SqQueue &Q,ElemType &x)
{
if(Q.front==Q.rear&&Q.tag==0)return false;
printf("\n此队列中目前有: %d个元素\n",QueueElemNumber(Q));
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
Q.tag=0;
return true;
}
//获得队头元素的值:
bool GetTop(SqQueue Q,ElemType &x)
{
if(Q.front==Q.rear&&Q.tag==0)return false;
x=Q.data[Q.front];
printf("\n此队列中目前有: %d个元素\n",QueueElemNumber(Q));
return true;
}
//主函数
int main()
{
int x;
SqQueue Q; //声明一个顺序队列Q
InitQueue(Q); //初始化顺序队列Q
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n向队列中输入元素:\n");
while(1)
{
scanf("%d",&x);
if(x==9999)
{
printf("\n输入结束\n");
break;
}
if(EnQueue(Q,x))printf("\n成功入队\n");
else{
printf("\n队列已满\n");
break;
}
}
if(GetTop(Q,x))printf("\n队头元素为: %d\n",x);
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n依次出队:\n");
while(DeQueue(Q,x))
{
printf("%d ",x);
}
printf("\n");
return 0;
}
二、队尾元素指向队尾指针的当前位置:
在针对队列的基本操作中,如何判空和判满?有以下三种办法
(1)牺牲掉一个存储空间:
#include<stdio.h>
#include<stdlib.h>
//顺序队列的数据类型定义
#define ElemType int
#define MaxSize 15
typedef struct{
ElemType data[MaxSize];
int front,rear;
}SqQueue;
//初始化顺序队列Q:
void InitQueue(SqQueue &Q)
{
Q.front=0;
Q.rear=MaxSize-1;
}
//判空操作:
bool QueueEmpty(SqQueue Q)
{
if((Q.rear+1)%MaxSize==Q.front)return true;
else return false;
}
//入队操作:
bool EnQueue(SqQueue &Q,ElemType x)
{
if((Q.rear+2)%MaxSize==Q.front)return false;
Q.rear=(Q.rear+1)%MaxSize;
Q.data[Q.rear]=x;
printf("\n队头指针: %d 队尾指针: %d 此队列中目前有: %d个元素\n",Q.front,Q.rear,(Q.rear+1+MaxSize-Q.front)%MaxSize);
return true;
}
//出队操作:
bool DeQueue(SqQueue &Q,ElemType &x)
{
if((Q.rear+1)%MaxSize==Q.front)return false;
printf("\n队头指针: %d 队尾指针: %d 此队列中目前有: %d个元素\n",Q.front,Q.rear,(Q.rear+1+MaxSize-Q.front)%MaxSize);
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return true;
}
//获得队头元素的值:
bool GetTop(SqQueue Q,ElemType &x)
{
if((Q.rear+1)%MaxSize==Q.front)return false;
x=Q.data[Q.front];
printf("\n队头指针: %d 队尾指针: %d 此队列中目前有: %d个元素\n",Q.front,Q.rear,(Q.rear+1+MaxSize-Q.front)%MaxSize);
return true;
}
//主函数
int main()
{
int x;
SqQueue Q; //声明一个顺序队列Q
InitQueue(Q); //初始化顺序队列Q
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n向队列中输入元素:\n");
while(1)
{
scanf("%d",&x);
if(x==9999)
{
printf("\n输入结束\n");
break;
}
if(EnQueue(Q,x))printf("\n成功入队\n");
else{
printf("\n队列已满\n");
break;
}
}
if(GetTop(Q,x))printf("\n队头元素为: %d\n",x);
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n依次出队:\n");
while(DeQueue(Q,x))
{
printf("%d ",x);
}
printf("\n");
return 0;
}
(2)在队列数据类型定义中设置变量size,用来保存当前队列内的元素个数,这个size随着入队和出队操作而发生变化:(这样就保证了每个存储空间都被利用):
#include<stdio.h>
#include<stdlib.h>
//顺序队列的数据类型定义
#define ElemType int
#define MaxSize 15
typedef struct{
ElemType data[MaxSize];
int front,rear;
int size;
}SqQueue;
//初始化顺序队列Q:
void InitQueue(SqQueue &Q)
{
Q.front=0;
Q.rear=MaxSize-1;
Q.size=0;
}
//判空操作:
bool QueueEmpty(SqQueue Q)
{
if(Q.size==0)return true;
else return false;
}
//入队操作:
bool EnQueue(SqQueue &Q,ElemType x)
{
if(Q.size==MaxSize)return false;
Q.rear=(Q.rear+1)%MaxSize;
Q.data[Q.rear]=x;
Q.size++;
printf("\n队头指针: %d 队尾指针: %d 此队列中目前有: %d个元素\n",Q.front,Q.rear,Q.size);
return true;
}
//出队操作:
bool DeQueue(SqQueue &Q,ElemType &x)
{
if(Q.size==0)return false;
printf("\n队头指针: %d 队尾指针: %d 此队列中目前有: %d个元素\n",Q.front,Q.rear,Q.size);
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
Q.size--;
return true;
}
//获得队头元素的值:
bool GetTop(SqQueue Q,ElemType &x)
{
if(Q.size==0)return false;
x=Q.data[Q.front];
printf("\n队头指针: %d 队尾指针: %d 此队列中目前有: %d个元素\n",Q.front,Q.rear,Q.size);
return true;
}
//主函数
int main()
{
int x;
SqQueue Q; //声明一个顺序队列Q
InitQueue(Q); //初始化顺序队列Q
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n向队列中输入元素:\n");
while(1)
{
scanf("%d",&x);
if(x==9999)
{
printf("\n输入结束\n");
break;
}
if(EnQueue(Q,x))printf("\n成功入队\n");
else{
printf("\n队列已满\n");
break;
}
}
if(GetTop(Q,x))printf("\n队头元素为: %d\n",x);
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n依次出队:\n");
while(DeQueue(Q,x))
{
printf("%d ",x);
}
printf("\n");
return 0;
}
(3)在队列的数据类型定义中增加一个成员tag,tag为0表示之前进行了删除操作,为1表示之前进行了插入操作,当队头指针和队尾指针相同时,如果tag=0表示队空,tag=1则表示队满:
#include<stdio.h>
#include<stdlib.h>
//顺序队列的数据类型定义
#define ElemType int
#define MaxSize 15
typedef struct{
ElemType data[MaxSize];
int front,rear;
int tag;
}SqQueue;
//统计当前队列中元素个数:
int QueueElemNumber(SqQueue &Q)
{
if(Q.tag==1&&(Q.rear+1)%MaxSize==Q.front)return MaxSize;
else return (Q.rear+1+MaxSize-Q.front)%MaxSize;
}
//初始化顺序队列Q:
void InitQueue(SqQueue &Q)
{
Q.front=0;
Q.rear=MaxSize-1;
Q.tag=0;
}
//判空操作:
bool QueueEmpty(SqQueue Q)
{
if((Q.rear+1)%MaxSize==Q.front&&Q.tag==0)return true;
else return false;
}
//入队操作:
bool EnQueue(SqQueue &Q,ElemType x)
{
if((Q.rear+1)%MaxSize==Q.front&&Q.tag==1)return false;
Q.rear=(Q.rear+1)%MaxSize;
Q.data[Q.rear]=x;
Q.tag=1;
printf("\n队头指针: %d 队尾指针: %d 此队列中目前有: %d个元素\n",Q.front,Q.rear,QueueElemNumber(Q));
return true;
}
//出队操作:
bool DeQueue(SqQueue &Q,ElemType &x)
{
if((Q.rear+1)%MaxSize==Q.front&&Q.tag==0)return false;
printf("\n队头指针: %d 队尾指针: %d 此队列中目前有: %d个元素\n",Q.front,Q.rear,QueueElemNumber(Q));
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
Q.tag=0;
return true;
}
//获得队头元素的值:
bool GetTop(SqQueue Q,ElemType &x)
{
if((Q.rear+1)%MaxSize==Q.front&&Q.tag==0)return false;
x=Q.data[Q.front];
printf("\n队头指针: %d 队尾指针: %d 此队列中目前有: %d个元素\n",Q.front,Q.rear,QueueElemNumber(Q));
return true;
}
//主函数
int main()
{
int x;
SqQueue Q; //声明一个顺序队列Q
InitQueue(Q); //初始化顺序队列Q
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n向队列中输入元素:\n");
while(1)
{
scanf("%d",&x);
if(x==9999)
{
printf("\n输入结束\n");
break;
}
if(EnQueue(Q,x))printf("\n成功入队\n");
else{
printf("\n队列已满\n");
break;
}
}
if(GetTop(Q,x))printf("\n队头元素为: %d\n",x);
if(QueueEmpty(Q))printf("\n此队列为空\n");
else printf("\n此队列不空\n");
printf("\n依次出队:\n");
while(DeQueue(Q,x))
{
printf("%d ",x);
}
printf("\n");
return 0;
}