1. 队列
- 第一个图是队列一开始为空,rear 和 front都 = -1;
- 因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及 rear分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear则是随着数据输入而改变
-
rear:队列最后一个元素所在的数组索引值
-
front:队列第一个元素所在的数组索引值-1
-
maxSize 是该队列的最大容量
用数组来实现队列
class QueueTest{
public static void main(String[] args){
Queue queue = new Queue(5);
System.out.println(queue.isEmpty());//true
queue.add(1);
queue.add(2);
queue.add(3);
int data = queue.get();
System.out.println(data);//1
}
}
//定义一个存放int数据的队列类
//取的时候从front取,存的时候从rear存
public class Queue {
private int maxSize;//队列容量
private int rear;//队列最后一个元素所在的数组索引值
private int front;//队列第一个元素所在的数组索引值-1
private int[] arr;//此队列内部用int[]来存放
//构造器
public Queue(int maxSize){
this.maxSize = maxSize;
rear = -1;
front = -1;
arr = new int[maxSize];
}
public boolean isEmpty(){
return rear == front;
}
public boolean isFull(){
return rear == maxSize-1;
}
public void add(int data){
if (isFull()){
System.out.println("队列已满~");
return;//之后便会跳出此方法,不会执行此方法中if语句下面的程序
}
rear++;
arr[rear] = data;
}
public int get(){
if (isEmpty()){
throw new RuntimeException("队列空~");
//throw语句本身就含有return,所以一旦抛出异常,就会退出此方法
}
front++;
return arr[front];
}
}
此队列的不足之处:
假设队列maxsize=5,当队列存满时,rear=4,front=1。此时取一个数后,rear=4,front=1。如果此时再想继续存的时候,会提示队列已经满了,因为rear=maxsize-1,明明只存了4个元素。
为了解决此问题,采用环形队列。
2.环形队列
对前面的数组模拟队列的优化,充分利用数组. 因此将数组看做是一个环形的。(通过取模的方式来实现即可)
思路如下:
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 // rear = 1 front = 0
6. 我们就可以在原来的队列上修改得到,一个环形队列
//环形队列
public class CircleQueue {
private int maxSize;//环形队列存满时的有效元素个数为maxSize-1个
private int front;//队列第一个元素的索引
private int rear;//队列最后一个非空元素索引的下一个位置,也就是说rear指向空的那个位置
private int[] arr;
public CircleQueue(int maxSize){
this.maxSize = maxSize;
front = 0;
rear = 0;
arr = new int[maxSize];
}
public boolean isEmpty(){
return rear == front;
}
public boolean isFull(){
return (rear+1)%maxSize==front;
}
public void add(int data){
if (isFull()){
System.out.println("队列已满~");
return;
}
arr[rear] = data;
rear = (rear+1)%maxSize;
}
public int get(){
if (isEmpty()){
throw new RuntimeException("队列空~");
//throw语句本身就含有return,所以一旦抛出异常,就会退出此方法
}
int value = arr[front];
front = (front+1)%maxSize;
return value;
}
}