-
队列是一个有序列表,可以用数组(顺序存储)或是链表(链式存储)来实现。
-
遵循先入先出的原则。先存入队列的数据,要先取出。后存入的要后取出
目录
1.数组模拟队列
用数组模拟队列,那就用数组来存储数据。此时需要定义一个数组,以及一个成员变量maxSize用于自定义容量大小。
因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及 rear分别记录队列前后端的下标。
class CircleArrayQueue{
private int front;//指向队列的第一个元素
private int rear;//指向队列的最后一个元素 的后一个位置
private int maxSize;
private int[] arr;
public CircleArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.front=0;
this.rear=0;
arr=new int[maxSize];
}
//判断是否已满
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++;
arr[rear]=n;
}
//获取队列的数据,出队列
public int getQueue(){
if(isEmpty()){
//如果队列为空,抛出异常
throw new RuntimeException("队列为空,不能取数据");
}
front++;
return arr[front];
}
//显示队列的所有数据
public void showQueue(){
if(isEmpty()){
System.out.println("队列空,无数据");
return;
}
for(int i=0;i<arr.length;i++){
System.out.println("arr["+i+"]="+ arr[i]);
}
}
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空,不能取数据");
}
return arr[front+1];
}
}
}
缺点:这样的队列只能使用一次,不能循环利用
改进思路:通过取模的方式,使其变为环形队列,实现循环利用
2.环形队列
用数组模拟队列时,不能循环利用
class CircleArrayQueue{
private int front;//指向队列的第一个元素
private int rear;//指向队列的最后一个元素 的后一个位置
private int maxSize;
private int[] arr;
public CircleArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.front=0;
this.rear=0;
arr=new int[maxSize];
}
//添加数据到队列
public void addQueue(int n){
if(isFull()){
System.out.println("队列已满");
return;
}
arr[rear]=n;
rear=(rear+1)%maxSize;
}
//获取数据,让数据出列
public int getQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空,不能取数据");
}
int n=front;
front=(front+1)%maxSize;
return arr[n];
}
//判断是否为空
public boolean isEmpty(){
return front == rear;
}
//判断是否满
public boolean isFull(){
return (rear+1)%maxSize==front;
}
//查看头数据
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空,不能取数据");
}
return arr[front];
}
//展示该队列
public void showQueue(){
if(isEmpty()){
System.out.println("队列空,无数据");
return;
}
for(int i=front;i<front+size();i++){
System.out.println("arr["+i%maxSize+"]="+ arr[i%maxSize]);
}
}
//队列中有效数据的个数
public int size(){
return (rear-front+maxSize)%maxSize;
}
}
由于rear指向队列的最后一个元素的后一个位置,实际上是该队列空出来了一个位置作为约定。该位置在环形链表中是动态变化的。
如果不空出一个位置作为约定,则会导致判断空和判断满的条件都是相同的。