队列

队列

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

队列(Queue)是一种先进先出(First In First Out)的线性表,简称FIFO。
允许插入的一端叫做队尾,删除的一端叫做队头。

队列_第1张图片
同样是线性表,队列也有类似的操作。不同的是队列是在队尾插入数据,在队头删除数据。

顺序队列

队列的基本操作

 1. getSize()	获取队列中有效元素的个数
 2. isEmpty()	判断是否为空
 3. clear()	清空队列
 4. enqueue()	入队
 5. dequeue()	出队
 6. getFront()	获取队首元素
 7. getRear()	获取队尾元素

空队列:
队列_第2张图片
这是一个长度为6空队列,此时队尾指针在头部。当我们向队列中插入元素时,效果如下图。
队列_第3张图片
插入数据时,队尾指针向后移动
插入一个数据,队尾指针移动到下标加1的位置

队列_第4张图片
当我们插入两个数据时,我们要删除一个数据,那么数据要从队头的位置开始删除,即现在下标为0的位置的数据要出队,下标为1的数据就要移动到下标为0的位置,同时队尾指针也要移动到下标为0的位置,即向左移动。

顺序存储的队列是是由ArrayList实现的。
即在数据元素入队的时候,相当于在 ArrayList表尾添加元素,时间复杂度为O(1)。
即在数据元素出队的时候,相当于在 ArrayList表头添加元素,时间复杂度为O(n)。
出队的时间复杂度为O(n)是因为当前只有队尾指针在移动,而队头始终不动,而且还要保证数据的连续性,所以出队的时间复杂度为O(n)。

为了解决出队的时间复杂度为O(n)的问题,我们有了循环队列这个概念。

队列_第5张图片
这里我们添加了队头指针,队头指针指向队列中第一个元素,队尾指针指向队列中最后一个元素。

队列_第6张图片
当我们引入队头指针时,出队数据元素时,队头指针向后移动1个下标的位置即可。

这样出队的时间复杂度就成了O(1)。

队列_第7张图片
但是这样优化的问题就是入队出队的时候数据元素是往后移动的,前面的部分位置就空下来了。且尾指针(Rear)不能继续后移了。

队列_第8张图片
为了解决上面的问题,我们让头指针和尾指针走到表尾的时候需要后移就重新指向头部。

队列_第9张图片
但是这个时候如何判断队列是满的还是空的?
但是这个时候我们不难发现,当队列已满和队列为空时,判定的条件都可以是(R+1)%n==F
因为这个条件同时满足两种情况,属于不严谨的情况,所以我们要再次优化。

队列_第10张图片
我们让尾指针始终指向数组中元素的后一个下标的位置,但这个位置里什么都不存,为null。
这样就可以解决判定队列已满和为空的条件重复了。

队列_第11张图片
我们不难看出这个时候队列为空,判断的条件是R==F。

队列_第12张图片

队列已满时,判断的条件是(R+1)%n==F。

你可能感兴趣的:(数据结构与算法,知识点)