队列:循环队列和双端队列/受限双端队列
文章目录
循环队列的长度
- 我们设循环队列的长度(队列中存在的元素数量(实际有效长度)) 为 L 为L 为L
- 为了方便计算,我们为循环队列打了两重下标,第二重开始的下标是虚拟的
- 第二重下标是第一重下标加上MaxSize后得到的(本例中MaxSize=8)
- 并且,队列头指针F总是沿着顺时针的方向追赶队尾指针R
- 我们允许R取得第二重下标,而F只允许取第一重下标中的值
- 这样,队列的元素数量(实际长度)就可以表示为:
- L ′ = R − F , 但是由于 R 可以取得第二重下标 , 因此 L ′ 可能是 L , 也可能是 L + M a x S i z e L'=R-F,但是由于R可以取得第二重下标,因此L'可能是L,也可能是L+MaxSize L′=R−F,但是由于R可以取得第二重下标,因此L′可能是L,也可能是L+MaxSize
- 而实际上,我们知道队列的元素长度 L L L是不会超过 M a x s i z e , 即 L ⩽ M a x s i z e Maxsize,即L \leqslant Maxsize Maxsize,即L⩽Maxsize;
- 恰好地,我们有一种运算(取模运算),
可以使得
L
+
K
×
M
a
x
S
i
z
e
→
L
可以使得L+K\times MaxSize\to L
可以使得L+K×MaxSize→L
- L = ( L + K × M a x S i z e ) % M a x S i z e L=(L+K\times MaxSize)\%MaxSize L=(L+K×MaxSize)%MaxSize
- 为了同一表达式,我们限制R的值只可以在第二重下标中取得,并把此时的值记为(
R
′
=
R
+
M
a
x
S
i
z
e
R'=R+MaxSize
R′=R+MaxSize)
- 从而 L = ( R ′ − F ) % M a x S i z e = ( R + M a x S i z e − F ) 从而L=(R'-F)\%MaxSize=(R+MaxSize-F)%MaxSize 从而L=(R′−F)%MaxSize=(R+MaxSize−F)
- 这样,队列的元素数量(实际长度)就可以表示为:
循环队列满/空判断
空判断
- 对于空队列,有
Q.rear==Q.front
满判断
- 判断队列满的方案有多种
- 牺牲掉一个位置来判断
队满
- 具体的判空条件为
(Q.rear+1)%MaxSize==Q.front
- 之所以这里要用 M a x S i z e MaxSize MaxSize, 是考虑到队满发生在 Q . r e a r = M a x S i z e − 1 是考虑到队满发生在Q.rear=MaxSize-1 是考虑到队满发生在Q.rear=MaxSize−1
- 这种情况下 Q . r e a r + 1 = M a x S i z e Q.rear+1=MaxSize Q.rear+1=MaxSize,这超过了数组下标的范围
- 而 Q . f r o n t 而Q.front 而Q.front不可能超过数组的下标范围,这样及时满足队满条件,也无法做出正确判断!
- 具体的判空条件为
- 在队列的数据类型中设置
size
成员来表示队列元素个数 - 或者设置
tag
成员来区分Q.front==Q.rear
是队满还是队空
- 牺牲掉一个位置来判断
循环队列入队
- 假设
rear
指针指向- 队尾元素本身,或者
- 队尾元素的下一个位置(空位)
- 检查队列是否已满(上面两种rear的定义情况都可以用以下条件进行判满)
(Q.rear+1)%MaxSize==Q.front
- 如果未满,则更新维护队尾指针
rear=(rear+1)%MaxSize
循环队列入队
front=(front+1)%MaxSize
受限双端队列
双入单出
1 | ||||||
---|---|---|---|---|---|---|
2 | 2 | |||||
3 | 3 | |||||
4 | 4 |
输入队列(按照左优先来组织(以1为中心))
- 共产生: 1 × 2 3 = 8 1\times 2^3=8 1×23=8中入队序列
2从左边入队
3从左侧入队
- 4321(4从左侧入队)
- 3214(4从右侧入队)
3从右侧入队
- 4213(4从左入队侧)
- 2134(4从右侧入队)
2从右边入队
3从左侧入队
- 43
12
- 3
12
4
3从右侧入队
- 4
12
3 12
34
小结:
-
对于单出双端队列,其入队序列,一个鲜明的特点在于入队序列的(第一个入队的元素)
起点
是1(或者是第一个进入队列的元素) -
起点的两侧序列的元素序号各自从起点向外侧递增(类似于抛物线)
双出单入
- 单入双处在进入序列是唯一的,但是在出队列上的可能性是很多的
- 甚至于,当入队序列的长度n不超过3,即 n ⩽ 3 n\leqslant 3 n⩽3的时候,任意的出队列都有可能(覆盖n的全排列 A n n = n ! A_n^n=n! Ann=n!)
- 而当队列长度达到4的时候(
n
>
3
n>3
n>3),那么会有一些出队列的序列是无法做到的,例如:
- 42xx打头的出队序列就无法实现
- 4213
- 4231
- 这是因为:
- 最后一个入队列的元素4作为第一个出队元素,那么可以确定,4出队的时候,所有其他元素(1,2,3)都还在队列中
- 导致2被加载1与3之间,无法在作为跟在4后面紧接着出列
- 但是同时我们发现,41xx和43xx都是可以实现的出度序列
- 42xx打头的出队序列就无法实现
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2021-09-17 embedded_ssd 1306 OLED (黑白Monochrome 7-pin)(128x64)引脚解释+ssd1306 OLED的Fritzing元件模块(fzpz)文件
2021-09-17 picGo@图床配置@分支设置(避坑)