队列是一个有序列表,可以用数组或链表来实现,遵循先入先出的原则!!!
增加数据是从队列的尾部添加,拿走数据从队列的顶端拿走!!先进来的先出去,需要用两个变量front和rear来记录队列的前后端 front跟着数据输出(取数据)而改变,rear随着数据输入(存数据)而改变
队列可以分为单向队列与环形队列
1.单向队列
使用场景,银行排号系统
判断条件:
1.当rear==maxSize-1时,无法再添加数据。。
2.front(指向队队列头 的前一个位置)初始化=-1
3.rear(指向队列尾部的数据)初始化=-1
想添加数据直接 array[++rear]=num;
想移除数据直接 return array[++front];
这个单向队列有一个问题:添加数据只能够添加一次。想要解决需要用到环形队列!!!
public class ArrayQueueDemo {
public static void main(String[] args) {
char key;
ArrayQueue aq = new ArrayQueue(4);
Scanner sc = new Scanner(System.in);
boolean loop=true;
while (loop){
//弹出一个菜单
System.out.println("s:显示队列");
System.out.println("g:移除数据");
System.out.println("a:添加数据");
System.out.println("e:退出数据");
key=sc.next().charAt(0);
switch (key){
case 's':
aq.show();
break;
case 'g':
int i = aq.get();
System.out.printf("取出数据是%d\n",i);
break;
case 'a':
int nextInt = sc.nextInt();
aq.add(nextInt);
break;
case 'e':
sc.close();
loop=false;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
//创建一个队列类
class ArrayQueue{
private int front;
private int rear;
private int maxSize;
private int[] array;
//创建队列的构造器
public ArrayQueue( int arrmaxSize){
maxSize=arrmaxSize;
array=new int[maxSize];
front=-1;//指向队列头部的前一个元素
rear=-1;//指向队列末尾数据
}
public boolean isFull(){
return rear==maxSize-1;
}
public boolean isEmpty(){
//true代表队列空,否代表队列不为空
return front==rear;
}
//
public void add(int num){
if(isFull()){
System.out.println("队列满了");
}
array[++rear]=num;
}
public int get(){
if(isEmpty()){
//抛出一个异常
throw new RuntimeException("队列空了,不能取数据");
}
return array[++front];
}
public void show(){
if(isEmpty()){
System.out.println("队列空了");
return;
}
for (int i =front; i <=rear ; i++) {
System.out.printf("array[%d]=%d\n",i,array[i]);
}
}
}
2.环形队列
上面数组出现的问题:数组使用一次就不能使用 解决的方式是将单向队列改造成环形队列围成一个圆,rear最后还会走向front的位置。
思路分析 :
front指向队列的第一个元素初始值为0
rear指向队列最后一个元素的后一个位置,初始值也是0
我们需要留出一个数组空间作为约定,这个空间不会被赋值,但随着数据的添加,这个约定空间会一直发生变化。
由于约定空间的存在当数组长度为5时有效数据仅有4个而不是5个 这一点需要着重注意!!是弄清楚环形队列的核心
限制条件:
队列空时: front= =rear;
队列满时: (rear+1)%maxSize= =front
有效数据个数(rear+maxSize-front)
环形队列添加数据front与rear的值都是会变化的可以循环重复的添加,要注意的点就是约定空间会变化!
class circleArray{
private int front;
private int rear;
private int maxSize;
private int[] array;
//创建队列的构造器
public circleArray( int arrmaxSize){
maxSize=arrmaxSize;
array=new int[maxSize];
front=0;//指向队列第一个元素
rear=0;//指向队列最后一个元素的后一个位置
}
public boolean isFull(){
return (rear+1)%maxSize==front;
}
public boolean isEmpty(){
//true代表队列空,否代表队列不为空
return front==rear;
}
//
public void add(int num){
if(isFull()){
System.out.println("队列满了");
return;
}
array[rear]=num;
rear = (rear + 1) % maxSize;
}
public int get(){
if(isEmpty()){
//抛出一个异常
throw new RuntimeException("队列空了,不能取数据");
}
int value=array[front];
front=(front+1)%maxSize;
return value;
}
public int head(){
if (isEmpty()){
throw new RuntimeException("队列为空");
}
return array[front];
}
public void show(){
if(isEmpty()){
System.out.println("队列空了");
return;
}
//从front开始遍历,遍历多少个元素即可。 front加上有效元素的个数
for (int i = front; i <front+(rear+maxSize-front)%maxSize ; i++) {
System.out.printf("array[%d]=%d\n",i%maxSize,array[i%maxSize]);
}
}
}