【栈与队列】之循环队列的实现(图文详细解释)

前言:本章基于《大话数据结构》和王卓老师的视频内容,为刚接触数据结构的初学者提供一些帮助。

💕如果我的文章对你有帮助,点赞、收藏、留言都是对我最大的动力

🐱‍👤我的上一篇文章:【栈与队列】之栈的链式存储(图文详细介绍!!)_﹏陈、词的博客-CSDN博客

4.10 队列的定义

 

队列:只允许在一端进行插入操作,而在另一端进行删除操作的线性表(头删尾插)。

特点:先进先出,允许插入的一段称为队尾,允许删除的一端称为队头。

4.11 队列的抽象数据类型

4.12 循环队列的实现与操作

在正式介绍循环队列之前,我们先来简单了解一下“真溢出”和“假溢出”。

“真溢出”:若front=0,rear=MAXQSIZE时,再继续入队的话,就要发生真溢出了。

“假溢出”:就是front不等于0,rear=MAXQSIZE时,再入队,就会发生假溢出。我们可以看到下图还有许多空出来的位置没用被利用。

 那该如何解决假溢出呢?第一种方法,就是将队中的元素依次先队头方向移动,而这种方法会浪费大量的时间,所以我们采取第二种方法,循环队列法。

4.12.1 循环队列的定义

循环队列:头尾相接的顺序存储结构的队列。如base[0]接在base[MAXQIZE-1]之后,若rear+1==M,就令rear=0;

那循环队列是如何实现的呢?我们接着往下看

主要的实现方法,就是利用模(mod,C语言中:%)运算

插入元素:Q.base[Q.rear]=x; Q.rear=(Q.rear+1)%MAXQSIZE;

删除元素:x=Q.base[Q.front]; Q.front=(Q.front+1)%MAXQSIZE;

这是我们需要注意的一个问题又出现了,就是队空和队满的条件都是front==rear,这又应该如何解决呢,这里有三个解决方法,

①另外设一个标志以区别队空、队满
②另设一个变量,记录元素个数

③少用一个元素空间

这里我们重点介绍第三种方法,少用一个元素空间。

 以上图为例:MAXQSIZE=6,front=4,rear=3,(3+1)%6=4,所以此时的队列是满的。

介绍完队满队空的情况后,我们简单来介绍一下队列的长度。

第一个图的长度为:Q.rear-Q.front

第二个图的长度为:MAXQSIZE-Q.front

第三个图的长度为:MAXQSIZE-Q.front+Q.rear+0

因此通用的计算队列长度的公式为: 

(rear-front+MAXQSIZE)%MAXQSIZE;

好了到这里我们已经知道什么是循环队列了,然后我们再来介绍一下队列的一些操作。

 4.12.2 循环队列的操作

结构定义

typedef struct {
	QElemType* base;//初始化的动态分配存储空间
	int front;//头指针
	int rear;//尾指针
}SqQueue;

队列的初始化

Status lnitQueue(SqQueue& Q)
{
	Q.base = new QElemType[MAXQSIZE];//分配数组空间
	//	Q.base=(QElemType*)malloc(MAXQSIZE(QElemType));
	if (!Q.base)exit(OVERFLOW);//存储分配失败
	Q.front = Q.rear = 0;//头指针尾指针置为0,队列为空
}

队列的长度

int QueueLength(SqQueue Q)
{
	return ((Q.rear - Q.front + MAXQSIZE) % MAXQSIZE);

}

队列的入队

Status EnQueue(SqQueue& Q, QElemType e)
{
	if ((Q.rear + 1) % MAXQSIZE == Q.front)return ERROR;//队满
	Q.base[Q.rear] = e;//新元素加入队尾
	Q.rear=(Q.rear + 1) % MAXQSIZE;//队尾指针+1
	return OK;
}

队列的出队

Status DeQueue(SqQueue& Q, QElemType& e)
{
	if (Q.front == Q.rear)
		return ERROR;//队空
	e = Q.base[Q.front];//保存队头元素
	Q.front = (Q.front + 1) % MAXQSIZE;//队头指针+1
	return OK;
}

取队头元素

QElemType GetHead(SqQueue Q)
{
	if (Q.front != Q.rear)//队列不为空
		return Q.base[Q.front];//返回队头指针元素的值,队头指针不变
}

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值