一、基本思路
1.初始化建空队列时,令front=rear=0;
2.插入元素时尾指针增1,删除队头元素时头指针增1,;
3.头指针始终指向队头元素,尾指针指向尾元素的下一个位置,如图;
4.臆造环状空间
(1)在a状态下依次插入J5,J6,J7得到b,在a状态下依次删除J3,J4,J5得到c;
(2)队列满或空时都有front=rear,两种解决方法:一是设置标志位,二是预留最后一个空间,作为满的条件;
5.如果用户无法估计队列最大长度,则使用循环链队列;
6.使用一维数组来模拟循环队列要注意rear和front之间的关系,就求队列长度而言,不能直接rear-front,设想这样一种情况
内存空间是6,填满队列后front为0,rear为5,现在把一个元素出队列,那么front要加1,现在下标为0的空间空出来了,
现在插入一个元素,rear的值就是0,所以要求此时队列长度,就是(rear-front+max)%max;
二 、代码如下
/*
项目名称:顺序循环队列的建立与基本操作
编译环境:VC++ 2008
作者相关:。。。
最后修改:2019.6.23
学习目标:初始化、销毁、清空、判空、求长、返回队头元素、插入元素、删除元素、输出队列中元素
注意事项:1.测试所有功能是否正常
2.Q.rear-Q.front + MAXQSIZE % MAXQSIZE
一维数组模拟的循环队列,假设有5块内存,front增加到5了,那么5之前的空间可以使用,
这样rear就到1所在的空间,这样rear就比5小了
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXQSIZE 100
#define ERROR 0
#define OK 1
typedef int ElemType;
typedef bool Status;
typedef struct{
ElemType *base;//初始化动态分配存储空间
int front;//若队列不空,指向队列头元素
int rear;//若队列不空,指向队列尾元素的下一个位置
}SqCQueue;
Status InitQueue(SqCQueue *Q);
Status DestroyQueue(SqCQueue *Q);
Status ClearQueue(SqCQueue *Q);
Status EmptyQueue(SqCQueue Q);
int LengthQueue(SqCQueue Q);
Status GetHead(SqCQueue Q,ElemType *e);
Status EnQueue(SqCQueue *Q,ElemType e);
Status DeQueue(SqCQueue *Q,ElemType *e);
Status TravelQueue(SqCQueue Q);
void visit(ElemType c);
int main()
{
SqCQueue q;
ElemType e;
InitQueue(&q);
if(EmptyQueue(q))
printf("循环队列为空!\n\n");
else
printf("循环队列非空!\n\n");
srand(time(0));
for(int i=0;i<10;i++)
{
e = rand()%100+1;
EnQueue(&q,e);
}
TravelQueue(q);
int k = LengthQueue(q);
printf("循环队列长度为:%d \n\n",k);
GetHead(q,&e);
printf("循环队列队首为:%d \n\n",e);
DeQueue(&q,&e);
DeQueue(&q,&e);
printf("循环队列第二次删除的元素为:%d \n\n",e);
TravelQueue(q);
EnQueue(&q,101);
printf("插入新元素后,");
TravelQueue(q);
ClearQueue(&q);
DestroyQueue(&q);
return 0;
}
Status InitQueue(SqCQueue *Q)
{
Q->base = (ElemType *)malloc(MAXQSIZE*sizeof(ElemType));
if(!Q->base)
return ERROR;
Q->front = Q->rear = 0;
return OK;
}
Status DestroyQueue(SqCQueue *Q)
{
free(Q->base);
return OK;
}
Status ClearQueue(SqCQueue *Q)
{
Q->front = Q->rear = 0;
return OK;
}
Status EmptyQueue(SqCQueue Q)
{
if(Q.front == Q.rear)
return true;
else
return false;
}
int LengthQueue(SqCQueue Q)
{
return (Q.rear-Q.front + MAXQSIZE) % MAXQSIZE;
}
Status GetHead(SqCQueue Q,ElemType *e)
{
if(EmptyQueue(Q))
return ERROR;
else
{
*e = *(Q.base+Q.front);
return OK;
}
}
Status EnQueue(SqCQueue *Q,ElemType e)
{
if((Q->rear+1)%MAXQSIZE == Q->front)//队列满,即rear指向front之前的位置时
return ERROR;
*(Q->base+Q->rear) = e;
Q->rear = (Q->rear+1) % MAXQSIZE;//假设max为6,本来rear=5(从0开始计数的),
//现在要到第一块内存,rear要等于0,实现了循环
return OK;
}
Status DeQueue(SqCQueue *Q,ElemType *e)
{
if(EmptyQueue(*Q))
return ERROR;
else
{
*e = *(Q->base+Q->front);
Q->front = (Q->front+1) % MAXQSIZE;//指向它的下个位置
return OK;
}
}
Status TravelQueue(SqCQueue Q)
{
printf("顺序循环队列内容: \n\n");
while(Q.front!=Q.rear)
{
visit(*(Q.base+Q.front));
Q.front = (Q.front+1) % MAXQSIZE;
}
printf("\n\n");
return OK;
}
void visit(ElemType c)
{
printf("%d ",c);
}
三、效果