目录
定义
循环队列是一种特殊的队列类型,它在数组的基础上实现。其实现方式是将数组的首尾相连,形成一个环状。这样在操作队列时,当往队列中漆加元素时,如果队列尾指针到达数组末尾,则在数组头部继续添加元素。当从队列中删除元素时,如果队列头指针到达数组末尾,则在数组头部继续删除元素。这样循环下去,队列就具有了循环的特性,即循环队列。
特点
先进先出,后进后出。
指针有头指针尾指针指示队内元素所在位置。
由尾部入队,头部出队。
结构体
#define MAXSIZE 100
typedef int DataType;
typedef struct
{
DataType data[MAXSIZE];
int front;
int rear;
}CirclesQueue;
初始化
头指针和尾指针指向相同位置
int init(CirclesQueue *Q)
{
Q->front = Q->rear = 0;
return 0;
}
入队
前提判断队列是否满,满无法入队。
循环队列用尾指针和最大存储值求模来确定指针下标。
数据插入。
int enqueue(CirclesQueue *Q, DataType x)
{
if(isfull(Q))
{
printf("队列已满!100001\n");
return 100001;
}
Q->rear = (Q->rear+1) % MAXSIZE;
Q->data[Q->rear] = x;
return 0;
}
效果
出队
前提判断是否为空,空无法出队。
出队从队首出队。
int dequeue(CirclesQueue *Q, DataType *x)
{
if(isempty(Q))
{
printf("队列为空!100002\n");
return 100002;
}
Q->front = (Q->front+1) % MAXSIZE;
*x = Q->data[Q->front];
return 0;
}
效果
判断队空或者队满
首尾指针指向相同为空。
尾指针最大循环值求模等于头指针为满。
//判断是否空
int isempty(CirclesQueue *Q)
{
return (Q->front == Q->rear) ? 1 : 0;
}
//判断是否满
int isfull(CirclesQueue *Q)
{
return (Q->rear+1)%MAXSIZE == Q->front ? 1 : 0;
}
效果
求队首元素
根据循环队列首指针与最大循环值求模确定头指针所指数据。
int get_top(CirclesQueue *Q, DataType *x)
{
return (Q->data[(Q->front + 1) % MAXSIZE]);
}
效果
求队长
尾指针与头指针做差再与最大循环之求和,循环队列需要与最大循环值求模。
int size(CirclesQueue *Q)
{
return ((Q->rear - Q->front +MAXSIZE) % MAXSIZE);
}
效果
输出队列
由头指针逐步增加遍历下角标所存数据,遍历出数据。
void print(CirclesQueue *Q, DataType *x)
{
int i;
i=(Q->front) % MAXSIZE;
printf("[");
do{
printf("%d;",Q->data[(i + 1%MAXSIZE)]);
i=(i+1)%MAXSIZE;
}
while(i!=Q->rear);
printf("]");
printf("\n");
}
效果
小结
为了能够充分地使用数组中的存储空间,克服”假溢出”现象,可以把数组的前端和后端连接起来,形成一个环形的表,即把存储队列元素的表从逻辑上看成一个环,成为循环队列。
main.c
#include <stdio.h>
#include "CirclesQueue.h"
int main(int argc, char* argv[])
{
CirclesQueue Q;
DataType x;
int cmd;
char yn;
do
{
printf("-----------循环队列演示-----------\n");
printf(" 1. 初始化\n");
printf(" 2. 入队\n");
printf(" 3. 出队\n");
printf(" 4. 队空\n");
printf(" 5. 队满\n");
printf(" 6. 队首\n");
printf(" 7. 队长\n");
printf(" 8. 打印队\n");
printf(" 9. 帮助\n");
printf(" 0. 退出\n");
printf(" 请选择(0~6):");
scanf("%d",&cmd);
switch(cmd)
{
case 1:
init(&Q);
printf("队列已初始化!\n");
break;
case 2:
printf("请输入要入队的元素x=");
scanf("%d", &x);
if(!enqueue(&Q,x))
{
printf("元素x=%d已入队\n", x);
}
break;
case 3:
printf("确定要出队(出队会将删除对首元素, y or n, n)?");
flushall();
scanf("%c", &yn);
if(yn == 'y' || yn == 'Y')
{
if(!dequeue(&Q,&x))
{
printf("队首元素【%d】已出队!\n", x);
}
}
break;
case 4:
if(isempty(&Q)){
printf("队空\n");
}else
printf("队不为空\n");
break;
case 5:
if(isfull(&Q)){
printf("队满\n");
}else
printf("队未满\n");
break;
case 6:
if(isempty(&Q)){
printf("队空\n");
}else
printf("队首元素:%d \n" ,get_top(&Q));
break;
case 7:
printf("队长:%d\n",size(&Q));
break;
case 8:
if(isempty(&Q)){
printf("队空\n");
}else
print(&Q,&x);
break;
case 9:
printf("本程序由sc于季老师设计上更改所得!");
break;
}
}while(cmd!=0);
return 0;
}
CirclesQueue.c
/*
CirclesQueue.c
*/
#include "CirclesQueue.h"
/*循环队列初始化*/
int init(CirclesQueue *Q)
{
Q->front = Q->rear = 0;
return 0;
}
/*入队*/
int enqueue(CirclesQueue *Q, DataType x)
{
if(isfull(Q))
{
printf("队列已满!100001\n");
return 100001;
}
Q->rear = (Q->rear+1) % MAXSIZE;
Q->data[Q->rear] = x;
return 0;
}
/*队满?*/
int isfull(CirclesQueue *Q)
{
return (Q->rear+1)%MAXSIZE == Q->front ? 1 : 0;
}
/*出队*/
int dequeue(CirclesQueue *Q, DataType *x)
{
if(isempty(Q))
{
printf("队列为空!100002\n");
return 100002;
}
Q->front = (Q->front+1) % MAXSIZE;
*x = Q->data[Q->front];
return 0;
}
/*队空*/
int isempty(CirclesQueue *Q)
{
return (Q->front == Q->rear) ? 1 : 0;
}
/*队首*/
int get_top(CirclesQueue *Q, DataType *x)
{
return (Q->data[(Q->front + 1) % MAXSIZE]);
}
/*队长*/
int size(CirclesQueue *Q)
{
return ((Q->rear - Q->front +MAXSIZE) % MAXSIZE);
}
/*输出*/
void print(CirclesQueue *Q, DataType *x)
{
int i;
i=(Q->front) % MAXSIZE;
printf("[");
do{
printf("%d;",Q->data[(i + 1%MAXSIZE)]);
i=(i+1)%MAXSIZE;
}
while(i!=Q->rear);
printf("]");
printf("\n");
}
CirclesQueue.h
/*
CirclesQueue.c
*/
#include "CirclesQueue.h"
/*循环队列初始化*/
int init(CirclesQueue *Q)
{
Q->front = Q->rear = 0;
return 0;
}
/*入队*/
int enqueue(CirclesQueue *Q, DataType x)
{
if(isfull(Q))
{
printf("队列已满!100001\n");
return 100001;
}
Q->rear = (Q->rear+1) % MAXSIZE;
Q->data[Q->rear] = x;
return 0;
}
/*队满?*/
int isfull(CirclesQueue *Q)
{
return (Q->rear+1)%MAXSIZE == Q->front ? 1 : 0;
}
/*出队*/
int dequeue(CirclesQueue *Q, DataType *x)
{
if(isempty(Q))
{
printf("队列为空!100002\n");
return 100002;
}
Q->front = (Q->front+1) % MAXSIZE;
*x = Q->data[Q->front];
return 0;
}
/*队空*/
int isempty(CirclesQueue *Q)
{
return (Q->front == Q->rear) ? 1 : 0;
}
/*队首*/
int get_top(CirclesQueue *Q, DataType *x)
{
return (Q->data[(Q->front + 1) % MAXSIZE]);
}
/*队长*/
int size(CirclesQueue *Q)
{
return ((Q->rear - Q->front +MAXSIZE) % MAXSIZE);
}
/*输出*/
void print(CirclesQueue *Q, DataType *x)
{
int i;
i=(Q->front) % MAXSIZE;
printf("[");
do{
printf("%d;",Q->data[(i + 1%MAXSIZE)]);
i=(i+1)%MAXSIZE;
}
while(i!=Q->rear);
printf("]");
printf("\n");
}