Java数据结构之队列(Queue)-理论图文形式

本篇博客的思路大纲:

首先介绍队列的概念和操作要求,然后介绍了循环队列的两种方式,一种顺序存储,一种是链式存储。并且介绍了基本的操作。

下一篇将会模拟实现队列。

思维导图:

1.队列的概念:

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

队列是一种先进先出(First In First Out)的线性表,简称FIFO。

允许插入的一端称为队尾:rear

允许删除的一端称为队头:front

假设队列是q=(a1,a2,......,an),那么a1就是队头元素,而an是队尾元素。这样我们就可以删除时,总是从a1开始,而插入时,列在最后。

2.队列的抽象数据类型:

同样是线性表,队列也有类似线性表的各种操作,不同的就是插入数据只能在队尾进行,删除数据只能在队头进行

同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。

3循环队列,队列的两种结构:

线性表有顺序存储和链式存储,栈是线性表,所以有这两种存储方式。同样,队列作为一种特殊的线性表,也同样存在这两种存储方式。

3.1队列的顺序存储结构:

3.1.1队列顺序存储的不足:(为了引入循环队列)

我们假设一个队列有n个元素,则顺序存储的队列需建立一个大于n的数组,并把队列的所有元素存储在数组的前n个单元,数组下标为0的一端即是队头。所谓的入队列操作,其实就是在队尾追加一个元素,不需要移动任何元素,因此时间复杂度为O(1)。 

入队:从队尾添加

出队:从队头删除元素

 但队尾rear不断地入队,线性表是有限的,rear就会指向一个不确定的地址

按上图,虽然rear到了一个不确定的位置,但是front之前的位置都是空的,所以此时队列并没有满。经过改善,如下图,如果将数组的首尾连起来,那么即使rear再往下走是下表为0但是此时指向是确定的而且队列是循环的,更好用,这个就是循环队列

rear再走一步: 

问题:顺序存储内存不足

3.2队列的链式存储结构

3.2.1循环队列的介绍

把队列的这种头尾相接的顺序存储结构称为循环队列,也就是原来的线性数组首尾相连,抽象成了上面圆形循环的数组了

当队列为空的时候,front和rear指向一致如图一,但循环列表满了的时候,也是如此front = rear,如图二

图一:

图二:

所以为了解决判断队列满了的时候的问题,有三种方案:

1.定义一个usedSize 来记录大小判断是否满

2.定义一个flag判断

3.使用公式:当队列空时,条件就是front=rear,当队列满时,我们修改其条件,保留一个元素空间。也就是说,队列满时,数组中还有一个空闲单元。

方法三的解释:由于rear可能比front大,也可能比front小,所以尽管它们只相差一个位置时就是满的情况,但也可能是相差整整一圈。所以若队列的最大尺寸为QueueSize,那么队列满的条件是(rear+1)%QueueSize==front(取模“%”的目的就是为了整合rear与front大小为一个问题)。

如图下,已经是队列满的情况,代入公式( 4 + 1)% 5 = 0 也就是 rear == front,此时就认为队列满了,而空的一个位置也就是说的空置一个单元。

问题:循环队列面临数组溢出的问题

所以引入链式存储结构。也就是地址不一定连续的链表。

3.2.3队列的链式存储结构及实现:

队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们把它简称为链队列。

空队列时,front和rear都指向头结点 

队列的链式存储结构——入队操作

直接在队尾插入结点

队列的链式存储结构——出队操作
 

删除队头的结点

出队操作时,就是头结点的后继结点出队,将头结点的后继改为它后面的结点,若链表除头结点外只剩一个元素时,则需将rear指向头结点

总结:

对于循环队列与链队列的比较,可以从两方面来考虑,从时间上,其实它们的基本操作都是常数时间,即都为O(1)的,不过循环队列是事先申请好空间,使用期间不释放,而对于链队列,每次申请和释放结点也会存在一些时间开销,如果入队出队频繁,则两者还是有细微差异。对于空间上来说,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的问题。而链队列不存在这个问题,尽管它需要一个指针域,会产生一些空间上的开销,但也可以接受。所以在空间上,链队列更加灵活。
总的来说,在可以确定队列长度最大值的情况下,建议用循环队列,如果你无法预估队列的长度时,则用链队列。
 

下一篇:

将会对队列进行模拟实现

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值