关于循环队列求队列值有多少值
在B站上学习了数据结构与算法的时候的时候,在环形队列里面有这样一个公式
(
r
e
a
r
+
m
a
x
S
i
z
e
−
f
r
o
n
t
)
%
m
a
x
S
i
z
e
(rear + maxSize - front) \% maxSize
(rear+maxSize−front)%maxSize
为了更加深入的了解这个算式为什么是这样,从而窥探算法的大门,于是我思考了一下,并且发现解法
看完这个保证细致到位,各种算式计算例题一步到位
转换我们的公式
( r e a r + m a x S i z e − f r o n t ) % m a x S i z e = ( r e a r − f r o n t + m a x S i z e ) % m a x S i z e (rear + maxSize - front) \% maxSize = (rear - front + maxSize) \% maxSize (rear+maxSize−front)%maxSize=(rear−front+maxSize)%maxSize
为什么要这样转换这个算式,因为这样方便我们进行理解
搞清楚几个问题,我们就能知道这个算式为什么要这样子
- 假如是一个正常的队列,我要怎么计算有多少有效数值?
- 当我们的索引超出我们的队列,如何让他回归数列?
- 当我们使用
%
的时候,rear和front谁在前谁在后对结果和结果的分析
计算正常队列的有效数字
正常数列就是我们之前学到的,数值只能一次性不能重新循环的版本,在那个版本里面计算有效数值非常简单
于是我们可以想象一个无法循环的循环队列,这听起来很怪,但是我们可以通过简化过后的循环队列来算值
有
效
数
值
=
r
e
a
r
−
f
r
o
n
t
有效数值 = rear - front
有效数值=rear−front
但是这里注意了,我们的rear并非真的是指向我们的最后一个元素,而是指向最后一个元素的后一个位置,所以公式应该变为
有 效 数 值 = r e a r + 1 − f r o n t 有效数值 = rear + 1 - front 有效数值=rear+1−front
当我们的索引超出队列,使用百分号让他回来
使用%可以让那些超过的数字回到队列里面来
比如当我们的rear已经指向了队列.length(实际上这是一个虚拟的位,实际上指向 - 队列.length - 1)
,这已经没有下一位,于是我们要想办法让他回到我们的队列开头
我们可以看到当我们队列长度为5的时候,不管我们的数值有多大,最终都无法超过5,请看下方GIF
rear和front在循环队列中的计算
当我们的rear在front的前面(队列已经超过了长度开始循环了)
这个时候你可以给我们的尾指针加上我们的数组长度让我们的队列变成这样:
这个时候我们的有效值计算公式是什么呢?
r
e
a
r
+
m
a
x
S
i
z
e
−
f
r
o
n
t
rear + maxSize - front
rear+maxSize−front
可以看到,已经有点上面的形状了,但是在这种情况下我们不需要加上百分号,可是这个算式就这样结束了吗?
当我们的rear在front的后面(正常情况)
虽然我们现在已经知道循环之后尾巴在前面的有效值怎么算,那么带入刚刚那个算式我们来看看这个正常情况能不能用:
现在使用算式 r e a r + m a x S i z e rear + maxSize rear+maxSize
这个时候玩笑就开大了,我们再使用 r e a r + m a x S i z e − f r o n t rear + maxSize - front rear+maxSize−front的话,结果就偏差到十万八千里去了
r e a r + m a x S i z e − f r o n t = 7 ( 个 有 效 元 素 , 实 际 上 只 有 3 个 ) rear + maxSize - front = 7(个有效元素,实际上只有3个) rear+maxSize−front=7(个有效元素,实际上只有3个)
我们需要让他落在我们的队列里面,所以我们给他百分号
( r e a r + m a x S i z e − f r o n t ) % m a x S i z e = 7 % 4 = 3 (rear + maxSize - front) \% maxSize = 7 \% 4 = 3 (rear+maxSize−front)%maxSize=7%4=3
可以看到加上百分号之后我们的算式又能用了,而且刚好等于正确答案3
测试一下我们当我们的rear在front的前面的情况是否能使用
KaTeX parse error: No such environment: align* at position 8: \begin{̲a̲l̲i̲g̲n̲*̲}̲ &(rear + maxSi…
备注:因为rear是指向当前位置的下一位,所以在参加运算的时候要+1
如图,当前尾指针的序号是1,但是此时我们需要给他+1,让他变成2再参与运算
到这里我们就结束了,最终我们得到结论如何算出一个循环队列的有效值
( r e a r + m a x S i z e − f r o n t ) % m a x S i z e (rear + maxSize - front) \% maxSize (rear+maxSize−front)%maxSize