目录
一、循环队列的概念
二、循环队列的定义
三、循环队列的相关方法
1、初始化及销毁
(1)初始化
(2)销毁
2、判空和判满
(1)判空
(2)判满
3、判断是否成功插入或删除元素
(1)插入
(2)删除
4、取队头和队尾的数据
(1)取队头数据
(2)取队尾数据
四、小结
上一篇文章我们介绍了队列,它遵循“先进先出”的原则。在队列中,有一种特殊的队列叫做循环队列,在运用中也常常遇到。今天我们来了解一下循环队列。
将顺序存储队列的元素的一维数组首尾相接,形成一个环状,如图所示,这种形状表示的队列称为循环队列。
在实现循环队列的方法中,我们可以考虑使用数组和链表。在循环队列中,我们首先知道的就是循环队列的大小,并且考虑到链表在插入数据和初始化时的扩容问题,相对而言使用数组容易一些,所以这里我们先使用数组进行理解。
首先我们需要定义队列的结构体,它要包含数组指针、头节点、尾节点以及循环队列的大小。因此它的定义如下:
(1)初始化
循环队列的初始化,首先想到的是开辟结构体的内存大小,然后就是开辟足够的数组空间,并且将其元素置为0。其中k指的是循环队列的有效数据个数,因此要置为要求的k。
(2)销毁
循环队列的销毁,即释放掉开辟的数组指针,并且将其置为空,最后释放掉结构体指针。
循环队列的方法中,最重要的便是判空和判满,因为不管是插入数据、删除数据,都要依据数组是否为空为满来分情况讨论。
(1)判空
在判空时,我们通过作图,不论何种情况,只需要判断head是否等于tail即可。
代码如下:
(2)判满
在判满时,我们知道tail指向的是最后一个数据的下一个位置, 正常情况下填满应该是如下图表示,但是这时tail+1的话数值会超出数组的下标,可能会形成越界访问的问题,因此我们要区分下面两个图中的情况,就需要分情况讨论。如果tail在0下标的位置,最后一个数据就在下标为k-1的位置,即数组的最后一个位置,这时我们如果只花了k个数组空间,那么条件与判空时相同,不容易判断出是空的还是满的,因此在判空和判满分析时,我们要多作一个空间来区分。

这时就容易判断了,只需要判断tail是在最后一个位置还是在正常的中间位置即可,我们可以利用三目操作符判断,写出以下代码:
或者我们可以用到巧妙地方法,首先展示一下代码:
我们在数学角度来看可以发现这样一个规律:一个数a加上一个数b之后再对b取模,结果还是a。我们这里采用的第二种方法就是用到了这个规律。我们把特殊情况的图拿下来:

这里我们就可以知道,让tail+1以后,在对k+1取模(这里的k表示循环队列,即数组可存放的数据个数),如果等于head,那么此时就是满的。
要判断是否成功插入或删除元素,并且在插入和删除之后返回true,否则返回false,这里我们就要判断循环队列是否为空为满了。
(1)插入
在执行插入操作之前,我们要判断如果为满,那么数组就无法插入数据,此时返回false;如果没有满,那么我们将给定值赋给tail下标位置之后让tail加一,但是为了防止越界,我们再让tail加一之后对k+1取模,那么代码如下:
(2)删除
与插入操作类似,首先判断是否为空,如果为空,那么我们无法删除数据,就返回false;如果数组中存放有数据,那么在删除之后,我们需要将head加一,同样为了防止出现在删除之前head等于k-1,即最后一个位置的情况,我们也要将其进行取模。
(1)取队头数据
取循环队列的队头数据,我们首先要判断是否为空,如果为空,返回-1,否则只需要返回head下标的值即可。
(2)取队尾数据
取队尾数据同样,首先要判断是否为空,如果为空,我们要返回-1,否则只需要返回tail下标之前的数据。但是要注意这里要注意tial不能越界,即要防止tail等于0的情况,因此我们需要取模操作:将tail减一(tail = -1)再加上k+1之后对k+1取模。
在实现循环队列时,不管是使用数组和链表都可以实现,作者个人觉得数组要比链表方便些,但都要注意判断空和满的时候,要分情况来看。数组可以按照以上提供的方法来分析,但是链表可能除了头指针和尾指针,还要设置另一个指针来指向尾节点的前一个节点。
如果各位大佬有相关需要补充或者改正的,欢迎在评论区评论讨论!
到此这篇环形队列(环形队列中有多少个元素可以根据队首指针)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/bcyy/12272.html