avatar

队列(使用Java数组模拟队列)

前言

将之前的知识整理一下

队列

队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作
简而言之,就是遵循先入先出原则。

数组模拟队列

队列是一个有序列表,可以用数组或是链表来实现
特点:遵循先入先出的原则。先存入队列的数据,要先取出,后存入的要后取出。

数组模拟队列思路

队列本身是有序列表,使用数组的结构来存储队列的数据
因为队列的输出、输入是分别从头部尾部来处理,因此需要两个变量 front 和 rear 分别记录队列头部尾部的下标,front 会随着数据输出而改变,而 rear 则是随着数据的输入而改变

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class ArrayQueue{
private int maxSize;//最大容量
private int front;//头指针
private int rear;//尾指针
private int[] arr;//底层数组

public ArrayQueue(int maxSize){
this.maxSize = maxSize;
arr = new int[maxSize];
this.front == -1;
this.rear == -1
}

//判断队列是否已满
public boolean isFull(){
return rear == manSize - 1;
}

//添加元素
public addQueue(int n){
//先判断队列满了没
if(isFull()){
throw new RuntimeException("队列已满");
}
rear++;//尾指针+1
arr[rear] = n;//赋值
}
//判断队列是否为空
public boolean isEmpty(){
return rear == front;
}
}
//取数据
public int get(){
if(isEmpty()){
throw new RuntimeException("队列为空,不能取数据");
}
front++;
return arr[front];
}

//显示队列的所有数据
public void showQueue(){
//判断队列是否空
if (isEmpty()) {
//通过抛出异常
throw new RuntimeException("队列为空,不能取数据!");
}
for (int i = 0;i<arr.length;i++) {
System.out.printf("arr[%d] = %d\n",i,arr[i]);
}
}

//显示队列的头数据,注意不是取出数据
public int headQueue(){
//判断是否为空
if (isEmpty()) {
//通过抛出异常
throw new RuntimeException("队列为空,不能取数据!");
}
return arr[front + 1];
}

思考问题

此队列有以下问题

  1. 数组不能得到充分利用,使用了一次就不能复用
  2. 将这个数组使用算法,改进成一个环形数组 取模 %

数组模拟环形队列

优化思路

  1. front变量的含义做一个调整 front指向队列的第一个元素,也就是说arr[front] 就说队列的第一个元素,front的初始值=0
  2. rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置,因为希望空出一个空间作为约定,rear的初始值=0
  3. 当队列满时,条件是 (rear+1)% maxSize = front【满】

    代码实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117

    /**
    * 使用数组模拟队列-编写一个ArrayQueue类
    */
    class CircleArray {
    /**
    * 表示数组的最大容量
    */
    private int maxSize;
    /**
    * front变量的含义做一个调整 front指向队列的第一个元素,
    * 也就是说arr[front] 就说队列的第一个元素,front的初始值=0
    */
    private int front;
    /**
    * rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置,
    * 因为希望空出一个空间作为约定,rear的初始值=0
    */
    private int rear;
    /**
    * 用于存放数据,模拟队列
    */
    private int[] arr;

    /**
    * 创建队列的构造器
    */
    public CircleArray(int arrManSize){
    maxSize = arrManSize;
    arr = new int[maxSize];
    }

    /**
    * 判断队列是否满
    */
    public boolean isFull(){
    return (rear+1) % maxSize == front;
    }

    /**
    * 判断队列是否为空
    */
    public boolean isEmpty(){
    return rear == front;
    }

    /**
    * 添加数据到队列
    */
    public void addQueue(int n){
    //判断队列是否满
    if(isFull()) {
    throw new RuntimeException("队列已满,不能加了!");
    }
    //让rear后移
    arr[rear] = n ;
    rear = (rear+1) % maxSize;
    }

    /**
    * 出队列
    */
    public int getQueue(){
    //判断队列是否空
    if (isEmpty()) {
    //通过抛出异常
    throw new RuntimeException("队列为空,不能取数据!");
    }
    //这里需要分析出 front 是指向队列的第一个元素
    //1、先把 front 对应的值保存在一个临时变量
    //2、将 front 后移
    //3、将临时保存的变量返回
    int value = arr[front];
    front = (front + 1) % maxSize;
    return value;
    }

    /**
    * 显示队列的所有数据
    */
    public void showQueue(){
    //判断队列是否空
    if (isEmpty()) {
    //通过抛出异常
    throw new RuntimeException("队列为空,不能取数据!");
    }
    //思路:从front开始遍历,遍历多少个元素
    //
    for (int i = front;i<front+size();i++) {
    System.out.printf("arr[%d] = %d\n",i%maxSize,arr[i%maxSize]);
    }
    }

    /**
    * 求出当前队列有效数据的个数
    */
    public int size(){
    //rear = 1
    //front = 2
    //maxsize = 3

    return (rear + maxSize - front) % maxSize;
    }

    /**
    * 显示队列的头数据,注意不是取出数据
    */
    public int headQueue(){
    //判断是否为空
    if (isEmpty()) {
    //通过抛出异常
    throw new RuntimeException("队列为空,不能取数据!");
    }
    return arr[front];
    }

    }
文章作者: Hobo
文章链接: https://hobo-clh.github.io/2020/06/08/%E9%98%9F%E5%88%97%EF%BC%88%E4%BD%BF%E7%94%A8Java%E6%95%B0%E7%BB%84%E6%A8%A1%E6%8B%9F%E9%98%9F%E5%88%97%EF%BC%89/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hobo's blog
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论