1.3 数组模拟队列
1.3.1 队列介绍
(1)队列是一个有序列表,可以用数组或者链表来实现
(2)遵循先入先出的原则。即先存入队列的数据要先取出,后存入的要后取出
(3)示意图
1.3.2 数组模拟队列思路
(1)队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图,其中maxSize
是该队列的最大容量
(2)因为队列的输出、输入是分别从前后端来处理,因此需要两个变量front
及rear
分别记录队列前后端的下标,front
回随着数据输出而改变,而rear
则是随着数据输入而改变
(3)当我们将数据存入队列时称为addQueue
, addQueue
的处理需要有两个步骤:思路分析
① 当尾指针往后移动:rear + 1
, 当front== rear [空]
② 若尾指针rear
小于队列的最大下标 maxSize - 1
,则将数据存入rear
所指的数组元素中,否则无法存入数据。rear == maxSize - 1
1.3.3 代码实现
class ArrayQueue { private int maxSize; private int front; private int rear; private int[] arr;
上方代码详解
(1)maxSize
:ArrayQueue
的最大容量
(2)front
:ArrayQueue
的头节点
(3)rear
:ArrayQueue的尾节点
(4)int[ ] arr
:该数组用于存放数据,模拟队列
public ArrayQueue(int arrMaxSize) { maxSize = arrMaxSize; arr = new int[maxSize]; front = -1; rear = -1; }
上方代码详解
(1)此处定义一个ArrayQueue
队列构造器,同时定义一个arrMaxSize
用于存储数组最大容量
(2)将arrMaxSize
赋值给ArrayQueue
的最大容量值
(3)开辟一个新的内存空间arr
用于存放数组,该数组作用为存放数据、模拟队列
(4)front
和rear
所指向的值并无实际意义,只是单纯赋值
public boolean isFull() { return rear == maxSize - 1; } public boolean isEmpty() { return rear == front; }
(1)isFull()
:该方法用于判断队列是否满,当队列满时,效果如下图,ArrayQueue
的尾节点指向MaxSize-1
,证明此时队列已满
(2)isEmpty()
:该方法用于判断队列是否空,当队列空时,效果如下图,ArrayQueue
的头尾节点均指向头部,整明此时队列里面没有数据,队列为空
(3)特别声明:MaxSize-1
的设定并非随意,考虑到数组实际可用空间大小为最大内存-1,故该数组模拟队列的实际可用大小为MaxSize-1
public void addQueue(int n) { if (isFull()) { System.out.println("队列已满,不能继续添加数据"); return; } rear++; arr[rear] = n; }
上方代码详解
(1)我们定义一个addQueue()
方法用于添加队列数据,定义一个n
变量作为插入的数值
(2)首先得判断队列是否为满,故if (isFull())
,如果为满,则 System.out.println
打印输出告知读者队列已满,并用return
进行返回
(3)若队列未满,则指向尾节点的rear
后移一位,腾出一个空间用于存放该数据,将n
变量赋值给数组模拟环形队列arr[]
中的rear
位置
public int getQueue() { if (isEmpty()) { throw new RuntimeException("队列空,不能取数据"); } front++; return arr[front]; }
上方代码详解
(1)我们定义一个getQueue()
方法用于获取队列中的数据
(2)首先得判断队列是否为空,故 if (isEmpty())
,如果为空,则抛出异常告知读者该队列为空,不能取出数据
(3)如果队列不为空,则front
后移。此处front
后移的原因是因为front
是指向头节点,当你把这个数据从队列取出来之后,front要自动前往下一个节点,故front++
(4)最后return
一下arr[]
中front
的位置
public void showQueue() { if (isEmpty()) { System.out.println("队列空的,没有数据"); return; } for (int i = 0; i < arr.length; i++) { System.out.printf("arr[%d] = %d\n", i, arr[i]); } }
上方代码详解
(1)我们定义一个showQueue()
方法用于展示队列中的数据
(2)首先得判断队列是否为空,故 if (isEmpty()) {
,如果为空,则System.out.printf
打印输出该队列为空,不能取出数据
(3)使用for循环来遍历arr[]
的长度,格式化输出该队列
public int headQueue() { if (isEmpty()) { throw new RuntimeException("队列空的,没有数据"); } return arr[front + 1]; }
上方代码详解
(1)我们定义一个headQueue()
方法用于展示队列的头节点(头数据)
(2)首先得判断队列是否为空,故 if (isEmpty())
,如果为空,则抛出异常告知读者该队列为空,不能取出数据
(3)若队列不为空,则取出arr[]
中front+1的位置的数据,此处front+1是因为由于数组下标的特性