一、队列的基础介绍
1、队列可用数组(顺序存储结构)或链表(链式存储结构)来实现;
2、遵循先入先出原则;
3、示意图:
二、用数组实现队列
1、队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如上图,其中maxSize是队列的最大容量;
2、队列的输入、输出分别从前后端处理,因此需要front和rear两个变量分别记录队列前后端的下标,其会随着数据输入而改变;
3、将数据存入的队列为“queue”:
①、对空:rear==front;
②、队满:rear=maxSize-1;
③、当尾指针 rear < maxSize – 1时,则将数据存入rear所指的数组中。
具体实现代码如下:
(1)、判断队列是否满
(2)、判断队列是否为空
(3)、添加数据到队列中
(4)、获取队列的数据,出队列;
(5)、显示当前队列数据;
(6)、显示队列的头数据,注意不是取出数据;
package com.ycx.queue;
import java.util.Scanner;
public class ArrayQueueDemo {
public static void main(String[] args) {
//测试
//创建一个队列
ArrayQueue queue = new ArrayQueue(3);
char key = ' ';//接受用户输入
Scanner input = new Scanner(System.in);
boolean flag = true; //控制循环 默认死循环
//输出菜单
while (flag){
System.out.println("s(show),显示队列");
System.out.println("e(exit),退出队列");
System.out.println("a(add),添加数据到队列");
System.out.println("g(get),从队列取出数据");
System.out.println("h(head),查看队列头的数据");
key=input.next().charAt(0);//接受收一个字符
switch (key){
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("输一个数");
int val=input.nextInt();
queue.addQueue(val);
break;
case 'g': //取出数据 因为方法里面抛出了异常 所以这里需要捕获
try{
int res=queue.getQueue();
System.out.printf("取出的数据为%d\n",res);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case 'h':
try{
int res=queue.headQueue();
System.out.printf("队列头的数据为%d\n",res);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case 'e': //退出程序
input.close();//关闭
flag=false;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
//一、使用数组模拟队列-编写一个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;//指向队列尾,指向队列尾的数据(即就是队列最后一个位置 )
}
//1.判断队列是否满
public boolean isFull(){
return rear==maxSize-1;//因为rear是从-1开始的(如果不理解就看笔记上的图)
}
//2.判断队列是否为空
public boolean isEmpty(){
return rear==front;
}
//3.添加数据到队列中
public void addQueue(int n){
//判断队列是否为满
if(isFull()){
System.out.println("队列已满,不能加入数据");
}
rear++;//rear 后移
arr[rear]=n; //也可以直接写成 arr[++rear]:rear先加再取值
}
//4.获取队列的数据,出队列
public int getQueue(){
if(isEmpty()){
throw new RuntimeException("队列空,不能取数据");
}
front++; //front 后移 因为front指向的是前一个元素(front=-1)
return arr[front];
}
//5.显示当前队列数据
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]); //格式化输出
}
}
//6.显示队列的头数据,注意不是取出数据
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
return arr[front+1]; //注意:front需要加1
}
}
运行结果如下:
三、问题分析并优化
(1)、缺点:数组只能使用一次,不能实现代码的复用。
(当把数组中所有的元素取出来后,数组为空,但无法添加元素进入数组)
(2)、优化:可以改成一个环形的数组(进行取余)。