一、队列是什么?
官方对队列的解释是这样的
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
我们可以将其与现实生活中的例子结合起来理解,如( 银行办业务,取排队小票,按顺序办业务; 超市结账,排队结账等),这些生活中随处可见的排队行为与计算机中的队列结构相对应,我们结合生活中的例子有助于我们更好的理解和学习队列这种数据结构
二、代码示例
1.在写代码之前我们需要做一些代码中的约定
- 我们使用数组来模拟队列
- front变量代表队列头部,rear变量代表队列尾部,maxsize变量代表队列的最大长度,arr数组代表队列的容器
- front变量和rear变量初始值为0即指向队列的第一个位置,maxsize的值由外部传入
- 判断队列是否为满的条件为:(rear + 1) % maxsize == front,此条件会预留数组的最后一个空间
- 判断队列是否为空的条件为: rear == front
- 判断队列中实际存在数量的公式为:(rear + maxsize -front) % maxsize
2.实现代码如下
class CircleArrayQueue{
private int maxsize;//数组大小
private int rear;//队列尾
private int front;//队列头
private int[] arr;//数组
public CircleArrayQueue(int maxsize){
this.maxsize = maxsize;
arr = new int[maxsize];
this.rear = 0;
this.front = 0;
}
//判断队列是否满
public boolean isFull(){
return (this.rear + 1) % this.maxsize == front;
}
//判断队列是否为空
public boolean isEmpty(){
return this.rear == this.front;
}
//入队列
public void addQueue(int n){
//先判断队列是否满
if(isFull()){
System.out.println("队列已满,无法入队列");
return;
}
//不满则可以继续入队
this.arr[rear] = n;
//注意此时rear需要考虑到复用的情况
this.rear = (this.rear + 1) % this.maxsize;
}
//出队列
public int getQueue(){
//先判断队列是否为空
if(isEmpty()){
throw new RuntimeException("队列为空,无法出队列");
}
//如果不为空则可继续出队列
int result = this.arr[this.front];
//注意此时front需要考虑到复用的情况
this.front = (this.front + 1) % maxsize;
return result;
}
//显示队列的所有数据
public void showQueue(){
for(int i = this.front; i < front + size(); i++) {
System.out.printf("arr[%d]=%d\n",i % maxsize,arr[i % maxsize]);
}
}
//获取队列中实际存在数量
private int size() {
return (this.rear + maxsize - front)%maxsize;
}
//现实队列的头数据
public int headQueue(){
//先判断队列是否为空
if(isEmpty()){
throw new RuntimeException("队列为空,没有数据");
}
return this.arr[this.front];
}
}
总结
- 主要关注取模算法,整个队列的复用实现主要是通过取模算法实现的。(重点)
- 注意判断是否为空,是否为满条件对整个队列流程持续进行的约束。