场景分析
银行排队:
上面三个柜台均有对应的顾客正在咨询中,其他顾客拿到手中的号码正在等待,当其中一个柜台服务完成之后就会通知下一个客户,客户手上的号码牌越靠前越先被通知;
基本介绍
1.队列是一个有序列表,可以使用数组或者链表来实现;
2.遵循先进先出的原则,即先存入队列的数据要先取出,后存入的要后取出;
应用实例
数组模拟队列
1.队列本身是有序列表,若使用数组的结构来存储队列的数据,那么我们需要规定其插入和取出的标记;
2.因此我们需要两个变量来记录队列的首尾,front记录队列头,rear来记录队列尾;还需要使用MaxSize来记录队列的最大容量;其中rear会根据数据的输入而改变,front会根据数据的输出而改变;
代码实现
@Setter
@Getter
public class ArrQueue {
private int [] arrQueue;
private int front;
private int rear;
private int maxSize;
//构造器,完成队列的初始化
public ArrQueue( int maxSize) {
this.maxSize = maxSize;
this.arrQueue=new int[maxSize];
this.front=-1; // 指向队列头的前一个位置
this.rear=-1; // 指向队列尾的数据
}
public boolean isFull(){
return getRear()==maxSize-1;
}
public boolean isEmpty(){
return getFront()==this.getRear();
}
/**
* @Author:strine
* 往队列添加元素
* */
public void addQueue(int ele){
// 判断队列是否已经满了
if (isFull()){
System.out.println("当前队列已经满");
}
rear++;
arrQueue[rear]=ele;
}
/**
* @Author:strine
* 在队列中取元素
* */
public int getElement(){
if (isEmpty()){
throw new RuntimeException("当前队列为空,请重试");
}
front++;
int ret = arrQueue[front];
arrQueue[front]=0;
return ret;
}
public void list(){
if (isEmpty()){
System.out.println("队列为空");
return;
}
for (int i = 0; i < arrQueue.length; i++) {
System.out.printf("%d\t",arrQueue[i]);
}
System.out.println();
}
}
public static void main(String[] args) {
ArrQueue arrQueue = new ArrQueue(12);
arrQueue.addQueue(1);
arrQueue.addQueue(2);
arrQueue.addQueue(3);
System.out.println("当前队列:");
arrQueue.list();
for (int i = 0; i < 4; i++) {
int element = arrQueue.getElement();
System.out.println("取数据:"+element);
}
}
效果展示
存在的问题
我们在取了元素之后,front后移了,但是元素被取出来了之后那个位置用不了了,也就是说,当我们添加元素rear到了maxSize的位置,我们即使把元素全部取出来之后,也不能再往里面加数据了,也就是说我们这个队列是一次性的,如下图所示:;
我们将该队列加满元素后再全部取出,再尝试往里面加数据,结果如下:
针对这种情况,我们考虑到队列的复用性,因此我们使用环形队列来对其进行优化;