一.队列(先入先出)
Maxsize为该队列最大容量
队列的输出和输入分别从前后端来处理,因此需要两个变量 front 和 rear 分别记录队列前后端的下标,front 会随数据 输出 而改变,而 rear 则是随着数据 输入 而改变。
如下图所示:
二.加入数据的思路分析
1)将尾指针往后移:rear +1,当front == rear【空】
2)若尾指针 rear 小于队列的最大下标 Maxsize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。rear == Maxsize -1【队列满】
三.初版代码
以下代码存在一个问题当存入三个数据后将其全部取出也没办法存入数据,因为其不是一个环形队列。
//数组模拟队列-编写一个ArrayQueue类
class ArrayQueue{
private int Maxsize; //表示数组最大容量
private int front;
private int rear;
private int[] arr; //用于存储数据,模拟队列
// 创建队列的构造器
public ArrayQueue(int arrMaxsize){
Maxsize = arrMaxsize;
arr = new int[Maxsize];
front = -1;//指向队列头部,分析出front 是指向队列头的前一个位置
rear = -1;//指向队尾,指向队尾的数据(即队列的最后一个数据)
}
// 判断队列是否满
public boolean isFull(){
return rear == Maxsize-1;
}
// 判断队列是否为空
public boolean isEmpty(){
return rear == front;
}
// 添加数据到队列
public void addQueue(int n){
// 判断队是否满
if(isFull()){
System.out.println("队列满,不能加入数据");
return;
}
rear++;//rear后移
arr[rear] = n;
}
// 获取队列的数据,出队列
public int getQueue(){
// 判断是否为空
if(isEmpty()){
// 通过抛出异常来处理
throw new RuntimeException("队列为空,不能取数据");
}
front++;//front 后移
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]);
}
}
// 显示队列的头数据,注意不是取出数据
public int headQueue(){
// 判断
if(isEmpty()){
throw new RuntimeException("队空,没有数据");
}
return arr[front+1];
}
四. 使用数组模拟环形队列思路分析
1)front 变量含义做一个调整:front 就指向队列第一个元素,也就是说arr[front] 就是队列的第一个元素,front 的初始值为0
2)rear 变量含义做一个调整:rear 指向队列的最后一个元素的后一个位置,因为希望空出一个空间做为约定,rear 的初始值为0
3)当队列满时,条件是(rear +1)%Maxsize = front【满】
4)当队列为空的条件,rear == front 【空】
5)当分析后,队列中有效的数据的个数(rear + Maxsize-front)%Maxsize
6)在原代码上修改,得到环形队列
五.数组模拟环形队列
此代码可进行重复add和get操作
//数组模拟队列-编写一个ArrayQueue类
class CircleArray{
private int Maxsize; //表示数组最大容量
// front变量的含义front 变量含义做一个调整:front 就指向队列第一个元素,也就是说arr[front] 就是队列的第一个元素
// front 的初始值为0
private int front;
// rear 变量含义做一个调整:rear 指向队列的最后一个元素的后一个位置,因为希望空出一个空间做为约定
// rear 的初始值为0
private int rear;
private int[] arr; //用于存储数据,模拟队列
// 创建队列的构造器
public CircleArray(int arrMaxsize){
Maxsize = arrMaxsize;
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()){
System.out.println("队列满,不能加入数据");
return;
}
// 直接将数据加入
arr[rear] = n;
// rear 后移,必须取模
rear = (rear +1) % Maxsize;
}
// 获取队列的数据,出队列
public int getQueue(){
// 判断是否为空
if(isEmpty()){
// 通过抛出异常来处理
throw new RuntimeException("队列为空,不能取数据");
}
//分析:front指向队列第一个元素
// 先把front对应的值保留到一个临时变量
// front后移
// 将临时变量返回
int value =arr[front];
front = (front+1)%Maxsize;
return value;
}
// 显示队列所有数据
public void showQueue(){
// 遍历
if(isEmpty()){
System.out.println("队空,没有数据");
return;
}
// 思路:从front开始遍历,遍历多少个元素
//
for (int i =front;i<front+size();i++){
System.out.printf("arr[%d]=%d\n",i % Maxsize,arr[i % Maxsize]);
}
}
// 求出当前队列有效数据
public int size(){
return (rear + Maxsize - front) % Maxsize;
}
// 显示队列的头数据,注意不是取出数据
public int headQueue(){
// 判断
if(isEmpty()){
throw new RuntimeException("队空,没有数据");
}
return arr[front];
}