一、基本介绍
- 队列是一个有序列表,可以用数组或链表来实现
- 遵循先入先出的原则,即先存入队列的数据,要先取出;后存入队列的数据,要后取出
- 示意图:
二、数组模拟队列
思路:
- 队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图,其中maxSize是该队列的最大容量。
- 因为队列的输出,输入是分别从队头和队尾来处理,因此需要两个变量front和rear分别记录队列前后端的下标,front会随着数据输出而改变,而rear则是随着数据输入而改变。
- 我们将数据存入队列时称为addQueue,addQueue的处理需要有两个步骤,分别是:将尾指针往后移,rear+1;若尾指针rear小于队列的最大下标maxSize-1,则将数据存入rear所指的数组元素中,否则无法存入数据。
- 队列初始:front和rear均为-1,front指向队头的前一个元素,rear指向队尾元素
- 队列为空:front==rear
- 队列为满:rear==maxSize-1
代码实现:
package com.atguigu.queue;
public class ArrayQueue {
private int maxSize;
private int front;
private int rear;
private int [] arr;
//构造函数,初始化队列
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
arr=new int [this.maxSize];
front=-1;
rear=-1;
}
//判断队列是否为满
public boolean isFull(){
if(rear==maxSize-1){
return true;
}else{
return false;
}
}
//判断队列是否为空
public boolean isEmpty(){
if(front==rear){
return true;
}else{
return false;
}
}
//入队
public void addQueue(int n){
if(this.isFull()==false){
rear++;
arr[rear]=n;
}else{
System.out.println("队列已满");
}
}
//出队
public int getQueue(){
if(this.isEmpty()==false){
front++;
return arr[front];
}else{
throw new RuntimeException("队列为空");
}
}
//打印队列内容
public void showQueue(){
if(this.isEmpty()){
System.out.println("队列为空");
}else{
System.out.print("[");
for(int i=front+1;i<=rear;i++){
if(i!=rear){
System.out.print(arr[i]+",");
}else{
System.out.print(arr[i]);
}
}
System.out.print("]");
System.out.println();
}
}
//获取队头元素
public int headQueue(){
if(this.isEmpty()==true){
throw new RuntimeException("队列为空");
}else{
return arr[front+1];
}
}
}
测试代码:
package com.atguigu.queue;
public class ArrayQueueDemo {
public static void main(String[] args) {
ArrayQueue arrayQueue=new ArrayQueue(5);
arrayQueue.showQueue();
System.out.println("-------------------------------------------------");
arrayQueue.addQueue(34);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue.addQueue(45);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue.addQueue(65);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue.addQueue(86);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue.addQueue(93);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue.addQueue(37);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
int temp1=arrayQueue.getQueue();
System.out.println("取出的元素是:"+temp1);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
int temp2=arrayQueue.getQueue();
System.out.println("取出的元素是:"+temp2);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
int temp3=arrayQueue.getQueue();
System.out.println("取出的元素是:"+temp3);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
int temp4=arrayQueue.getQueue();
System.out.println("取出的元素是:"+temp4);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue.addQueue(100);
System.out.print("队列的元素:");
arrayQueue.showQueue();
System.out.println("队列的队头元素:"+arrayQueue.headQueue());
}
}
效果图:
问题分析:
- 目前数组使用一次就不能继续使用了,没有达到复用的效果
- 将这个数组使用算法,改进成一个环形的队列(取模)
三、数组模拟环形队列
思路:
对前面的数组模拟队列的优化,充分利用数组,因此将数组看做是一个环形的(通过取模的方式来实现)
在环形队列中,如图b所示,队列为满,则front==rear;如图c所示,队列为空时,则front==rear。因此无法判断队列为满或为空,处理方法:少用一个元素空间,约定以“队列头指针在队尾指针的下一位置(值环形的下一个位置)上”作为队满的标志
分析:
- front变量的含义做一个调整:front指向队列的第一个元素,也就是arr[front]就是队列的第一个元素,front的初始值为0
- rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置,因为希望它空出一个空间作为约定,rear的初始值为0
- 队列为满:(rear+1)%maxSize==front
- 队列为空:rear==front
- 队列中元素的个数(对长):(rear-front+maxSize)%maxSize
代码实现:
package com.atguigu.queue;
public class ArrayQueue1 {
private int maxSize;
private int front;
private int rear;
private int [] arr;
//构造函数,初始化队列
public ArrayQueue1(int maxSize) {
this.maxSize = maxSize;
arr=new int [this.maxSize];
front=0;
rear=0;
}
//判断队列是否已满
public boolean isFull(){
if((this.rear+1)%this.maxSize==front){
return true;
}else{
return false;
}
}
//判断队列是否为空
public boolean isEmpty(){
if(this.rear==this.front){
return true;
}else{
return false;
}
}
//入队
public void addQueue(int n){
if(this.isFull()){
System.out.println("队列已满,不可添加元素");
}else{
arr[rear]=n;
rear=(rear+1)%this.maxSize; //将rear后移一位,这里必须考虑环形队列(取模)
}
}
//出队
public int getQueue(){
if(this.isEmpty()){
throw new RuntimeException("队列为空,不可取出元素");
}else{
int temp=arr[front]; //1.先把front对应的值保存到一个临时变量
front=(front+1)%maxSize; //2.将front后移一位
return temp; //3.将临时变量返回
}
}
//获取队列长度
public int getLength(){
return (rear-front+maxSize)%maxSize;
}
//打印队列元素
public void showQueue(){
if(this.isEmpty()){
System.out.println("队列为空,无法显示队列");
}else{
System.out.print("[");
for(int i=front;i<(this.getLength()+this.front);i++){
if(i!=(this.getLength()+this.front-1)){
System.out.print(arr[i%this.maxSize]+",");
}else{
System.out.print(arr[i%this.maxSize]);
}
}
System.out.println("]");
}
}
//获取队头元素
public int headQueue(){
if(this.isEmpty()){
throw new RuntimeException("队列为空,没有队头元素");
}else{
return arr[front];
}
}
}
package com.atguigu.queue;
public class ArrayQueueDemo1 {
public static void main(String[] args) {
ArrayQueue1 arrayQueue1=new ArrayQueue1(5);
System.out.println("队列的初始长度:"+arrayQueue1.getLength());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(34);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(78);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(43);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(88);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(22);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
int temp1=arrayQueue1.getQueue();
System.out.println("取出的元素是:"+temp1);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
int temp2=arrayQueue1.getQueue();
System.out.println("取出的元素是:"+temp2);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
int temp3=arrayQueue1.getQueue();
System.out.println("取出的元素是:"+temp3);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
int temp4=arrayQueue1.getQueue();
System.out.println("取出的元素是:"+temp4);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
// System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(100);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(200);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(300);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(400);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(500);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
int temp5=arrayQueue1.getQueue();
System.out.println("取出的元素是:"+temp5);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
int temp6=arrayQueue1.getQueue();
System.out.println("取出的元素是:"+temp6);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
int temp7=arrayQueue1.getQueue();
System.out.println("取出的元素是:"+temp7);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
int temp8=arrayQueue1.getQueue();
System.out.println("取出的元素是:"+temp8);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
// System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(1000);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(2000);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(3000);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
System.out.println("-------------------------------------------------");
arrayQueue1.addQueue(4000);
System.out.println("队列的当前长度:"+arrayQueue1.getLength());
System.out.print("队列的元素:");
arrayQueue1.showQueue();
System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
}
}
效果图: