循环队列(顺序存储结构)C语言


一、队列

为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。

循环队列和普通队列有所不同,需要注意的是队空队满
为了区分队空还是队满的情况,有多种处理方式(这里选的是第一种):

方式1: 牺牲一个单元来区分队空和队满,入队时少用一个队列单元,即约定以"队头指针在队尾指针的下一位置作为队满的标志"
方式2: 增设表示队列元素个数的数据成员size,此时,队空和队满时都有front==rear。
方式3: 增设tag数据成员以区分队满还是队空

二、代码

1.头文件与宏定义

#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define MAXSIZE 50
#define QueueElemType char

2.循环队列的定义及主要操作

typedef struct {
	QueueElemType elem[MAXSIZE];
	int front;  //头
	int rear;	//尾
}SeqQueue;

// 初始化
void InitQueue(SeqQueue* Q) {
	Q->front = Q->rear = 0;
}

// 判断队列是否为空
int IsEmpty(SeqQueue Q) {
	if (Q.front == Q.rear) {
		return TRUE;
	}
	else {
		return FALSE;
	}
}

// 入队
int EnterQueue(SeqQueue* Q, QueueElemType x) {
	if ((Q->rear + 1) % MAXSIZE == Q->front) {
		//队列已满
		return FALSE;
	}
	else {
		Q->elem[Q->rear] = x;
		Q->rear = (Q->rear + 1) % MAXSIZE;	//重新设置队尾
		return TRUE;
	}
}

// 出队
int DeleteQueue(SeqQueue* Q, QueueElemType* x) {
	if (Q->front == Q->rear) {
		//队列为空
		return FALSE;
	}
	else {
		*x = Q->elem[Q->front];
		Q->front = (Q->front + 1) % MAXSIZE;
		return TRUE;
	}
}

// 求队的长度
int LenQueue(SeqQueue Q) {
	return ((Q.rear + MAXSIZE - Q.front) % MAXSIZE);
}

// 输出队中元素
int PrintQueue(SeqQueue Q) {
	if (Q.front == Q.rear) {
		//队列为空
		return FALSE;
	}
	while(TRUE) {
		if (Q.rear == Q.front) {
			return TRUE;
		}
		else {
			printf("%c ", Q.elem[Q.front++]);
		}
	}
}

3.主函数(测试函数)

int main() {
	SeqQueue Q;
	int i, n, flag, len;
	QueueElemType x;
	//初始化循环队列
	InitQueue(&Q);

	//判断队列是否为空
	printf("当前队列是否为空: ");
	flag = IsEmpty(Q);
	if (flag) {
		printf(" 当前队列为空。\n");
	}
	else {
		printf(" 当前队列不为空。\n");
	}

	//入队
	printf("请输入入队数量:\n");
	scanf("%d", &n);
	getchar();
	printf("请输入元素:\n");
	for (i = 0; i < n; i++) {
		x = getchar();
		getchar();	
		flag = EnterQueue(&Q, x);
		if (!flag) {
			printf("当前队列已满!!\n");
			break;
		}
	}

	//出队
	printf("出对一个元素并输出\n");
	flag = DeleteQueue(&Q, &x);
	if (flag) {
		printf("%c \n", x);
	}
	else {
		printf("队列为空!!!\n");
	}

	//当前队列元素的个数
	len = LenQueue(Q);
	printf("当前队列元素的个数:%d\n", len);

	//入队
	printf("请输入入队数量:\n");
	scanf("%d", &n);
	getchar();
	printf("请输入元素:\n");
	for (i = 0; i < n; i++) {
		x = getchar();
		getchar();
		flag = EnterQueue(&Q, x);
		if (!flag) {
			printf("当前队列已满!!\n");
			break;
		}
	}

	//当前队列元素的个数
	len = LenQueue(Q);
	printf("当前队列元素的个数:%d\n", len);

	//所有元素出队
	printf("所有元素出队:\n");
	while (TRUE){
		flag = DeleteQueue(&Q, &x);
		if (!flag) {
			break;
		}
		else {
			printf("%c ", x);
		}
	}
	printf("\n");

	//判断队列是否为空
	printf("当前队列是否为空: ");
	flag = IsEmpty(Q);
	if (flag) {
		printf(" 当前队列为空。\n");
	}
	else {
		printf(" 当前队列不为空。\n");
	}

	return 0;
}

三.运行结果

在这里插入图片描述

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鹹魚不鹹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值