循环队列(顺序表示和实现)

队列有两种存储表示,顺序表示链式表示

顺序栈相类似,在队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外,尚需附设两个整型变量front和rear分别指向队列头元素和队列尾元素的位置(即称为头指针和尾指针)。

为了在C语言中描述方便起见,在此约定:初始化创建空队列时,令front=rear=0,每当插入新的队列尾元素时,尾指针rear增1:每当删除队列头元素时,头指针front增1。因此,在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置,详情如下图所示
在这里插入图片描述
假设当前队列分配的最大空间为6,则当队列处于图3.12(d)所示的状态时不可再继续插入新的队尾元素,否则会出现溢出现象,即因数组越界而导致程序的非法操作错误。事实上,此时队列的实际可用内存并未占满:所以这种现象称为“假溢出”。这是由“队尾入队,对头出队”这种受限制的操作造成的。

一个较好的办法就是使顺序队列逻辑上称为一个环状的空间,称之为循环队列

循环队列的思想就是使它首尾逻辑相连,可以有多种写法。重要在于
队列满时有哪几种情况。
头尾指针应如何变化以确保不溢出和正确指向。
等…

C++代码

#include<iostream>
#define MAX 5
using namespace std;
typedef struct
{
	int *base;//存储空间基地址 
	int front;//头指针 
	int rear;//尾指针 
}Sqqueue;
bool initqueue(Sqqueue &q)
{
	q.base = new int[MAX];
	if(!q.base)
	return false;
	q.front = q.rear = 0;
	for( int i=0; i<MAX; i++ )
	q.base[i] = 0;
	return true;
}
void input(Sqqueue &q,int num)
{
	int data;
	//判断队列已满条件,一种是front****rear,头指针在开始位置,尾指针在最后位置,该队列满!
	//                另一种是**front/rear*** ,头尾指针指向同一位置,且位置的两边都存有元素! 
	if(( q.front == (q.rear+1)%MAX  && q.base[q.rear]!=0 )|| ( q.front==q.rear && q.base[0]!=0 && q.base[MAX-1]!=0 ) )
	{
		cout<<"队列已满,无法再存!" <<endl<<endl;
		return;
	}
	for( int i=0; i<num; i++ )
	{
		cin>>data;
		q.base[q.rear] = data;
		cout<<"第"<<i+1<<"个入队的元素为 "<<data<<endl;
		if( ( q.front == (q.rear+1)%MAX  && q.base[q.rear]!=0 ) || ( q.front==q.rear && q.base[0]!=0 && q.base[4]!=0 ) )
		{
			cout<<"队列已满,无法再存!" <<endl<<endl;
			return;
		}
		q.rear = (q.rear+1)%MAX;
	}
	cout<<endl;
}
void output(Sqqueue &q,int num)
{
	for( int i=0; i<num; i++ )
	{
		if(q.base[q.front]==0)
		{
			cout<<"已没有元素可出队!"<<endl<<endl;
			break;
		}
		cout<<"第"<<i+1<<"个出队的元素为 "<<q.base[q.front]<<endl;
		q.base[q.front] = 0;
		q.front = (q.front+1)%MAX;
	}
	cout<<endl;
	if( (( q.rear+1)%MAX==0 && q.base[q.rear]!=0) || q.base[q.rear]!=0 )//当尾指针指向最后一个地址空间且已存入数据时,尾指针回到开始位置,即队列的循环性 
	q.rear = ( q.rear+1)%MAX;
}
int main()
{
	int num;
	string s;
	Sqqueue q;
	initqueue(q);
	while( true )
	{
		cout<<"***你想要执行的操作(in/out *)及个数***"<<endl;
		cin>>s>>num;
		if( s=="in" )
		input(q,num);
		
		else if( s=="out" )
		{
			cout<<"\n出队列(先进先出)顺序如下(顺序存储结构)\n\n";
			output(q,num);
		}
	}
}

结果

***你想要执行的操作(in/out *)及个数***
in 4
11个入队的元素为 1
22个入队的元素为 2
33个入队的元素为 3
44个入队的元素为 4

***你想要执行的操作(in/out *)及个数***
out 5

出队列(先进先出)顺序如下(顺序存储结构)

第1个出队的元素为 12个出队的元素为 23个出队的元素为 34个出队的元素为 4
已没有元素可出队!


***你想要执行的操作(in/out *)及个数***
in 3
51个入队的元素为 5
62个入队的元素为 6
73个入队的元素为 7

***你想要执行的操作(in/out *)及个数***
in 3
11个入队的元素为 1
82个入队的元素为 8
队列已满,无法再存!

***你想要执行的操作(in/out *)及个数***
in 1
队列已满,无法再存!

***你想要执行的操作(in/out *)及个数***
out 3

出队列(先进先出)顺序如下(顺序存储结构)

第1个出队的元素为 52个出队的元素为 63个出队的元素为 7

***你想要执行的操作(in/out *)及个数***
in 1
51个入队的元素为 5

***你想要执行的操作(in/out *)及个数***
out 5

出队列(先进先出)顺序如下(顺序存储结构)

第1个出队的元素为 12个出队的元素为 83个出队的元素为 5
已没有元素可出队!


***你想要执行的操作(in/out *)及个数***

代码只是简单实现循环顺序队列的基本思想
代码中注释写得不多,如有问题可以评论留言,我会回复的,欢迎各位大佬的指导
转载需说明!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

eeeasyFan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值