前言
将之前的知识整理一下
队列
队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作
简而言之,就是遵循先入先出原则。
数组模拟队列
队列是一个有序列表,可以用数组或是链表来实现
特点:遵循先入先出的原则。先存入队列的数据,要先取出,后存入的要后取出。
数组模拟队列思路
队列本身是有序列表,使用数组的结构来存储队列的数据
因为队列的输出、输入是分别从头部尾部来处理,因此需要两个变量 front 和 rear 分别记录队列头部尾部的下标,front 会随着数据输出而改变,而 rear 则是随着数据的输入而改变
代码实现
1 | public class ArrayQueue{ |
思考问题
此队列有以下问题
- 数组不能得到充分利用,使用了一次就不能复用
- 将这个数组使用算法,改进成一个环形数组 取模 %
数组模拟环形队列
优化思路
- front变量的含义做一个调整 front指向队列的第一个元素,也就是说arr[front] 就说队列的第一个元素,front的初始值=0
- rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置,因为希望空出一个空间作为约定,rear的初始值=0
- 当队列满时,条件是 (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];
}
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hobo's blog!
评论