队列介绍
队列是一个有序列表,可以用数组或者链表实现
遵循先进先出的原则:先存入队列的数据,要先取出,后存入的数据,要后取出
使用数组模拟队列示意图
数组模拟队列思路:
-
队列本身是有序列表,如果使用数组的结构来存储队列的数据,则队列数组的声明如上图,maxSize是队列的最大容量。
-
因为队列的的输出、输入分别从前后端来处理,所以需要两个变量fornt个rear分别记录前后端的下标,front会随着数据输出而改变,而rear会随着数据输入而改变。
-
当我们将数据存入队列时成为addQueue,addQueue有两个步骤。
<1.将为指针往后移rear++
<2.若尾指针rear小于队列的最大下标maxSize,则将数据存入rear所指的数组元素中,否则无法存入数据。
rear==maxSize-1 则对列为满
个人理解
存值得时候rear后移,取值的时候front后移,初始值都为-1
所以存的方式为 arr[++rear]=i;//从arr的第一个索引开始存
取的方式为return arr[++front];//从第一个索引开始取(先进先出)
获取头部数据的方式为 return arr[front+1] //因为front是指向队列的前一个位置
编程步骤:
1. 用数组模拟一个队列,编写一个ArrayQueue类
class ArrayQueue{
private int maxSize;//数组最大容量
private int front;//队列头
private int rear;//队列尾
private int []arr;//存放数据,模拟队列
}
2. 创建队列构造器
//创建队列构造器
public ArrayQueue(int arrMaxSize){
maxSize=arrMaxSize;
arr=new int[maxSize];//创建队列数组
front=-1;//指向队列头部(队列头的前一个位置)
rear=-1;//指向队列尾部(队列的最后一个数据)
}
3. 判断队列是否为满
//判断队列是否为满
public boolean isFull(){
return rear==maxSize-1;
}
4. 判断队列是否为空
//判断队列是否为空
public boolean isEmpty(){
return front==rear;
}
5. 添加数据到队列中
//添加数据到队列
public void addQueue(int n){
//判断是否满
if (isFull()){
System.out.println("队列满,不能添加数据");
return;
}
rear++;
arr[rear]=n;
}
6. 获取队列数据(出队列)
//获取队列数据,出队列
public int getQueue(){
//判断是否为空
if (isEmpty()){
throw new RuntimeException("队列空,不能取数据");
}
front++;
return arr[front];
}
7. 显示队列
//显示队列
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]);
}
}
8. 显示队列头数据
//显示队列头数据(不是取数据)
public int headQueue(){
if (isEmpty()){
throw new RuntimeException("队列空没有数据源");
}
return arr[front+1];
}
9. 在主方法中测试
public static void main(String[] args) {
//测试
//1.创建一个队列
ArrayQueue arrayQueue = new ArrayQueue(3);
Scanner scanner = new Scanner(System.in);
boolean loop=true;
while (loop){
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):查看队列头的数据");
String next = scanner.next();
switch (next){
case "s":
arrayQueue.showQueue();
break;
case "a":
System.out.println("请输入一个数");
int i = scanner.nextInt();
arrayQueue.addQueue(i);
break;
case "g":
try {
int res= arrayQueue.getQueue();
System.out.println("取出的数据是 "+res);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case "h":
try {
int res=arrayQueue.headQueue();
System.out.println("队列头数据是" +res);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case "e":
scanner.close();
loop=false;
break;
}
}
System.out.println("程序退出");
}
问提分析
这个数组使用一次就不能再使用,不能复用
优化
将这个数组改造成一个环形的队列,循环使用
详情请看下篇文章