数组模拟队列之深度解析

580 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第N天,点击查看活动详情

1.3 数组模拟队列

1.3.1 队列介绍

(1)队列是一个有序列表,可以用数组或者链表来实现

(2)遵循先入先出的原则。即先存入队列的数据要先取出,后存入的要后取出

(3)示意图

image.png

1.3.2 数组模拟队列思路

(1)队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图,其中maxSize是该队列的最大容量

(2)因为队列的输出、输入是分别从前后端来处理,因此需要两个变量frontrear分别记录队列前后端的下标,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)maxSizeArrayQueue最大容量

(2)frontArrayQueue头节点

(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)frontrear所指向的值并无实际意义,只是单纯赋值

   public boolean isFull() {
        return rear == maxSize - 1;
    }
    public boolean isEmpty() {
        return rear == front;
    }

(1)isFull():该方法用于判断队列是否满,当队列满时,效果如下图,ArrayQueue的尾节点指向MaxSize-1,证明此时队列已满

image.png

(2)isEmpty():该方法用于判断队列是否空,当队列空时,效果如下图,ArrayQueue的头尾节点均指向头部,整明此时队列里面没有数据,队列为空

image.png

(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是因为由于数组下标的特性