队列:循环队列和双端队列/受限双端队列

循环队列的长度

image-20220916092735070

  • 我们设循环队列的长度(队列中存在的元素数量(实际有效长度)) 为 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=RF,但是由于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,LMaxsize;
      • 恰好地,我们有一种运算(取模运算), 可以使得 L + K × M a x S i z e → L 可以使得L+K\times MaxSize\to L 可以使得L+K×MaxSizeL
        • 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=(RF)%MaxSize=(R+MaxSizeF)

循环队列满/空判断

空判断

  • 对于空队列,有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=MaxSize1
        • 这种情况下 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
22
33
44

输入队列(按照左优先来组织(以1为中心))

  • 共产生: 1 × 2 3 = 8 1\times 2^3=8 1×23=8中入队序列
2从左边入队
3从左侧入队
  1. 4321(4从左侧入队)
  2. 3214(4从右侧入队)
3从右侧入队
  1. 4213(4从左入队侧)
  2. 2134(4从右侧入队)
2从右边入队
3从左侧入队
  1. 4312
  2. 3124
3从右侧入队
  1. 4123
  2. 1234
小结:
  • 对于单出双端队列,其入队序列,一个鲜明的特点在于入队序列的(第一个入队的元素)起点是1(或者是第一个进入队列的元素)

  • 起点的两侧序列的元素序号各自从起点向外侧递增(类似于抛物线)

双出单入

  • 单入双处在进入序列是唯一的,但是在出队列上的可能性是很多的
  • 甚至于,当入队序列的长度n不超过3,即 n ⩽ 3 n\leqslant 3 n3的时候,任意的出队列都有可能(覆盖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都是可以实现的出度序列
posted @   xuchaoxin1375  阅读(18)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享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@图床配置@分支设置(避坑)
点击右上角即可分享
微信分享提示