循环队列的实现

定义:

    队列又称为先进先出线性表,插入操作只能在队尾进行,删除操作只能在队首进行。

    而循环队列是队列的一种特殊形式,循环队列是一种线性数据结构,其操作表现基于先进先出原则,并且队尾被连接在队首之后以形成一个循环。

特点:

    是可以充分利用数组空间,避免了普通队列因出队操作导致空间浪费的问题。当队尾指针到达数组的末尾时,它可以回到数组的起始位置,形成一个环形结构。循环队列的入队和出队操作都是在队头和队尾进行的。

环形队列的实现

初始化
//初始化循环队列 
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 getLength(CirclesQueue *Q) {  
    return (Q->rear - Q->front + MAXSIZE) % MAXSIZE; 
} 
得到队首元素
//得到队首元素  
DataType getFront(CirclesQueue* Q) {  
    int i;
    i = (Q -> front) %MAXSIZE;
    return Q -> data[(i + 1 % MAXSIZE)];
}
输出队列
//输出队列 
void printQueue(CirclesQueue *Q) {
    int i;
    if (isempty(Q)) {  
        printf("Queue is empty.\n");  
        return;  
    }  
    i = (Q -> front) %MAXSIZE;
    do{
        printf(" %d",Q -> data[(i + 1 % MAXSIZE)]);
        i = (i+1) %MAXSIZE;
    }while(i != Q -> rear);
}

运行截图

完整代码

CirclesQueue.h
#define MAXSIZE 10

typedef int DataType;

typedef struct
{
	DataType data[MAXSIZE];
	int front;
	int rear;
}CirclesQueue;

//循环队列初始化
int init(CirclesQueue *Q);

//入队
int enqueue(CirclesQueue *Q, DataType x);

//队满
int isfull(CirclesQueue *Q);

//出队
int dequeue(CirclesQueue *Q, DataType *);

//队空
int isempty(CirclesQueue *Q);

//输出队列内容  
void printQueue(CirclesQueue *Q);

//获取队列长度  
int getLength(CirclesQueue *Q);

//获取队首元素
DataType getFront(CirclesQueue* Q);
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;
}

//输出队列 
void printQueue(CirclesQueue *Q) {
    int i;
    if (isempty(Q)) {  
        printf("Queue is empty.\n");  
        return;  
    }  
    i = (Q -> front) %MAXSIZE;
    do{
        printf(" %d",Q -> data[(i + 1 % MAXSIZE)]);
        i = (i+1) %MAXSIZE;
    }while(i != Q -> rear);
}

//得到队列长度  
int getLength(CirclesQueue *Q) {  
    return (Q->rear - Q->front + MAXSIZE) % MAXSIZE; 
} 

//得到队首元素  
DataType getFront(CirclesQueue* Q) {  
    int i;
    i = (Q -> front) %MAXSIZE;
    return Q -> data[(i + 1 % MAXSIZE)];
}

welcome.h
char welcome[] =
		"       ...╭ ╯╭ ╯╭ ╯\n\
   . ╭╩═╮.╔════╗╔════╗╔════╗╔════╗\n\
    ╭╯嘟嘟  ~~???? ╠╣~~???╠╣??? ╠╣~????~╟\n\
    ╰⊙═⊙╯╚⊙═⊙╝╚⊙═⊙╝╚⊙═⊙╝ ╚⊙═⊙╝\n";
main.c
#include <stdio.h>
#include "CirclesQueue.h"
#include <string.h>
#include <stdlib.h>
#include "welcome.h"

int main(int argc, char* argv[])
{

   
	CirclesQueue Q;
	DataType x;
	int cmd;
	char yn;
    
	int i = 0;  
	int m = 0; 
	int n = 0;
	
    for(i=0;i<strlen(welcome);i++)
	{
		printf("%c",welcome[i]);
		for(m=0;m<10000;m++)
			for(n=0;n<1000;n++)
			{
				;
			}
	}


	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(" 0. 退出\n");
		printf(" 请选择(0~8):");
		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)?");
			getchar();
			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:
			printf("队列长度:%d\n",getLength(&Q));
			break;
		case 7:
		    printf("队列首元素: %d\n", getFront(&Q));  
            break;
		case 8:
			printf("输出:");
			printQueue(&Q);
			printf("\n");
			break;
		}

	}while(cmd!=0);


	return 0;
}

小结

循队列是一种特殊的队列,它可以充分利用数组空间,避免了普通队列在出队后留下空间无法利用的问题。循环队列的实现需要注意队列为空和队列已满的情况,可以通过队头和队尾指针的位置关系来判断。循环队列的初始化、插入、删除和打印操作都需要特别处理。在实现循环队列时,需要定义一个结构体来存储队列的头指针、尾指针和数据,同时需要定义一些函数来实现队列的各种操作。循环队列的实现可以通过数组或链表来实现,其中数组实现的循环队列比较常见。

参考文献

循环队列详解-CSDN博客

数据结构和算法-循环队列 - 掘金 (juejin.cn)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值