1.什么是队列
队列是我们平时生活中比较常见的一种数据结构,比如银行的叫号排队就是一个典型的队列,或者我们更常见的食堂排队打饭,等等等等
a.队列是一个有序列表,可以是数组或者链表来实现
b.队列遵循先进先出的原则,即现存入队列的数据要先取出,后存入队列的数据要后取出
2.数组模拟队列的思路
队列本身是有序列表,若使用数组结构来存储队列的数据,则队列数组的声明如下图,其中maxsize是该队列的最大容量,因为队列的输出,输入是分别从队列头和队列尾来处理,因此需要两个变量front和rear来记录队列头和队列尾的下标,front会随着数据的输出而改变,rear会根据数据的输入而改变
当我们将数据存入队列时需要注意两个步骤
(1):将尾指针rear向后移:rear=rear+1,且当front=rear时队列为空
(2):当尾指针rear小于队列最大容量maxsize-1,则说明队列未满,此时可以向队列插入数据,若rear=maxsize-1,则说明队列已满,此时将不能插入数据
3.数组模拟队列的代码实现
public class ArrayQueue {
private int maxsize;//队列的最大长度
private int front;//头部指针
private int rear;//尾部指针
private int arr[]; //队列数组
//队列构造器
public void queue(int size) {
maxsize=size;
front = -1;
rear = -1;
arr =new int [maxsize];
}
//判断队列是否为空
public boolean isempty() {
return front==rear;
}
//判断队列是否已满
public boolean isfull() {
return rear==maxsize-1;
}
//添加数据到队列
public void addqueue(int n) {
if(isfull()) {
System.out.println("队列数据已满");
}else {
rear++;
arr[rear]=n;
}
}
//从队列取出数据
public int getqueue() {
if(isempty()) {
throw new RuntimeException("此队列无数据");
}else {
front++;
return arr[front];
}
}
//返回当前队列的有效数据个数
public int size() {
return rear-front;
}
//显示当前队列中的所有数据
public void show() {
for(int i=0;i<rear;i++) {
System.out.print(arr[i]+" ");
}
}
}
4.数组实现队列的缺陷
虽然我们已经实现了用数组去实现一个队列,但是其中还是有缺陷,那就是数组使用了一次就无法再使用了,比如将队列插满数据后如果你取数据后再插你会发现并不能将数据插进去,原因很简单,因为在数据插满后rear和front的值就没有再改变过,所以插不进去,所以我们为了提高复用性用取模的方式改进让它变成一个环形队列
5.环形队列
与之前的不同
a.环形队列尾索引的下一个头索引时则表示队列已满,即将队列容量空出一个作为约定,这个在做判断满的时候需要注意(rear+1)%maxsize==front则表示队列已满
b.rear=front时表示队列为空
6.环形队列的代码实现
public class CircleQueue {
private int maxsize;//队列的最大长度
private int front;//头部指针
private int rear;//尾部指针
private int arr[]; //队列数组
//队列构造器
public void queue(int size) {
maxsize=size+1;
arr =new int [maxsize];
}
//判断队列是否为空
public boolean isempty() {
return front==rear;
}
//判断队列是否已满
public boolean isfull() {
return (rear+1)%maxsize==front;
}
//添加数据到队列
public void addqueue(int n) {
if(isfull()) {
System.out.println("队列数据已满");
}else {
arr[rear]=n;
rear=(rear+1)%maxsize;
System.out.println(rear);
}
}
//从队列取出数据
public int getqueue() {
if(isempty()) {
throw new RuntimeException("此队列无数据");
}else {
int value=arr[front];
front=(front+1)%maxsize;
return value;
}
}
//返回当前队列的有效数据个数
public int size() {
return (rear-front+maxsize)%maxsize;
}
public void show() {
for(int i=front;i<front+size();i++) {
System.out.print(arr[i]+" ");
}
}
}
此时我们来测试下
public class CircleQueueDemo {
public static void main(String[] args) {
CircleQueue c=new CircleQueue();
c.queue(5);
c.addqueue(20);
c.addqueue(30);
c.addqueue(40);
c.addqueue(50);
c.addqueue(60);
c.show();
c.getqueue();
c.getqueue();
c.getqueue();
c.getqueue();
System.out.println();
c.addqueue(123);
c.show();
}
}
这样一个数组就来重复使用了,一个环形队列也就出来了