队列
- 队列是一个有序列表,可以使用数组或者链表实现
- 遵循先入先出的原则。 即先存入列表的数据要先取出,后存入的要后取出。
采用数组模拟队列
思路分析
- front指向队列的头部的前一个位置,初始为-1
- rear指向队列的尾部(尾部这个位置)。初始为-1
- 当有数据输入时,front不动,real向上移,当rear = maxSize - 1 时,队列满,无法再加入数据;
- 当有数据 输出时,队列的尾部不动,头部上移,rear = front 时,队列空,此时无数据可以取出
- 先进先出
代码
import java.util.Scanner;
public class ArrayQueueDemo{
public static void main(String[] args){
//创建队列,大小为3
ArrayQueue aq=new ArrayQueue(2);
Scanner ss=new Scanner(System.in);
//用来接收输入的字符
char c=' ';
boolean loop=true;
while(loop){
//界面
System.out.println("s(showQueue):显示队列");
System.out.println("a(addQueue):插入队列");
System.out.println("g(getQueue):出队列");
System.out.println("h(headQueue):显示队列的头");
System.out.println("e(exit):退出");
//取第0位的字符
c=ss.next().charAt(0);
switch(c){
case 's':
aq.showQueue();
break;
case 'a':
System.out.println("请输入要进入队列的数据:");
int data=ss.nextInt();
aq.addQueue(data);
break;
case 'g':
try{
int data2=aq.getQueue();
System.out.printf("%d出队列",data2);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case 'h':
try{
int data3=aq.headQueue();
System.out.printf("%d是现在队列的队头\n",data3);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case 'e':
loop=false;
//关闭输入
ss.close();
System.out.println("退出……");
break;
default:
break;
}
}
}
}
class ArrayQueue{
private int MaxSize;
private int[] arr;
private int front;
private int real;
//构造方法
ArrayQueue(int maxsize){
//创建队列
MaxSize=maxsize;
arr=new int[MaxSize];
front=-1;
real=-1;
}
//判断队列是否为空
public boolean isEmpty(){
return front==real;
}
//判断队列是否满了
public boolean isFull(){
return real==MaxSize-1;
}
//插入数据
public void addQueue(int data){
if(isFull()){
System.out.println("队列已满,插入失败");
return;
}
arr[++real]=data;
System.out.printf("%d入队成功\n",data);
}
//出队列
public int getQueue(){
if(isEmpty())
//throw会自动返回,所以不用return
throw new RuntimeException("队列为空,无法出队");
front++;
return arr[front];
}
//显示队列中所有数据,arr中数据一直都在
//因为arr存储的依然是数组的地址
//值没有被覆盖掉
public void showQueue(){
if(isEmpty()){
System.out.println("队列为空,没有数据");
return;
}
for(int i=0;i<MaxSize;i++){
System.out.printf("arr[%d]=%d\n",i,arr[i]);
}
}
//显示头数据,不出队
public int headQueue(){
if(isEmpty()){
//System.out.println("队列为空,没有头数据");
//return;
throw new RuntimeException("队列为空,没有头数据");
}
return arr[front+1];
}
}
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
队列为空,没有数据
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
11
11入队成功
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
22
22入队成功
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
33
队列已满,插入失败
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
g
11出队列s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
g
22出队列s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
g
队列为空,无法出队
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
44
队列已满,插入失败
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
e
退出……
问题及优化
-
结束后要关闭输入
-
数组不能重复用,即使空也不能再入队,队列不能循环使用,没有达到复用效果
-
使用算法改进成环形队列:取模
注意:
数组为空,只是逻辑上判断为空,内存里还是满的