队列
概述
有序列表,可以用数组、链表实现。先进先出原则。
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。(百度百科)
数组实现
需要一个maxSize来表示队列的长度
需要front、rear 记录队列的头和尾的数据的下标
数据加入队列
需要rear尾指针向后移,raer++
当raer = front 时,队列为空
当rear = maxSize - 1 时,队列满
数据出队列
先判断是否为空,然后弹出下标为 front+1 的下标的数据
代码实现
public class ArrayQueue {
private int maxSize;
private int front;
private int rear;
private int array[];
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
front = -1;
rear = -1;
array = new int[maxSize];
}
//判断队列是否为空
public boolean isEmpty(){
return front == rear;
}
//判断队列是否满
public boolean isFull(){
return rear == maxSize - 1;
}
//向队列中添加数据
public void addQueue(int num){
if (isFull()){
System.out.println("队列已满");
return;
}
rear++;
array[rear] = num;
}
//取出头部数据
public int getQueue(){
if (isEmpty()){
throw new RuntimeException("队列为空");
}
front++;
return array[front];
}
//展示所有数据
public void showQueue() {
if (isEmpty()){
System.out.println("队列为空");
return;
}
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]+"\t");
}
System.out.println();
}
}
环形队列
上面的实现方法其实是有问题的,因为队列满了以后把数据取出来以后,后面的数据不会前移,这就会导致rear一直也不会前移,rear和maxSize一直相等,则不能再向其中添加数据
解决方法
maxsize: 预留一个位置出来作为缓冲区,可存储的数据数量 会比 实际数组的大小 减1
rear:指向最后一个元素的后一个位置,当超过maxsize的时候就指向0
front:始终指向第一个元素
满的条件:(rear+1)%maxsize == front
空的条件:rear == front
有效个数的计算: (rear +maxSize - front)%maxSize
代码实现
public class ArrayCircleQueue {
private int maxSize;
private int front;
private int rear;
private int array[];
public ArrayCircleQueue(int maxSize) {
this.maxSize = maxSize + 1;//因为“可存储的数据数量 会比 实际数组的大小 减1”,所以这里数组大小比你希望存储的数据的maxSize加1,后面用到maxSize的地方都是数组的maxSize
front = 0;
rear = 0;
array = new int[this.maxSize];
}
//判断队列是否为空
public boolean isEmpty(){
return front == rear;
}
//判断队列是否满
public boolean isFull(){
return (rear + 1) % maxSize == front;
}
//向队列中添加数据
public void addQueue(int num){
if (isFull()){
System.out.println("队列已满");
return;
}
array[rear] = num;
rear = (rear+1) % maxSize;
}
//取出头部数据
public int getQueue(){
if (isEmpty()){
throw new RuntimeException("队列为空");
}
int f = array[front];
front = (front+1)%maxSize;
return f;
}
//展示所有数据
public void showQueue() {
if (isEmpty()){
System.out.println("队列为空");
return;
}
//循环从front即头部开始,循环getSize()次,即 有效数据的个数次
for (int i = front; i < front + getSize(); i++) {
//这里的输出数组的下标为 i % maxSize,,这样如果front为maxSize的情况下,取余之后,取得的下标即是0,也就是下一个元素
System.out.print(array[i%maxSize]+"\t");
}
System.out.println();
}
//返回有效数据的个数
public int getSize(){
return (rear +maxSize - front) % maxSize;
}
public int getHead() {
if (isEmpty()){
throw new RuntimeException("队列为空");
}
return array[front];
}
}
代码测试
public class QueueTest {
public static void main(String[] args) {
ArrayQueue arrayQueue = new ArrayQueue(3);
arrayQueue.addQueue(1);
arrayQueue.addQueue(2);
arrayQueue.addQueue(3);
arrayQueue.showQueue();
System.out.println(arrayQueue.getQueue());
System.out.println(arrayQueue.getQueue());
System.out.println(arrayQueue.getQueue());
arrayQueue.showQueue();
System.out.println("================================");
ArrayCircleQueue circleQueue = new ArrayCircleQueue(3);
circleQueue.addQueue(1);
circleQueue.addQueue(2);
circleQueue.addQueue(3);
circleQueue.showQueue();
circleQueue.getQueue();
circleQueue.addQueue(4);
circleQueue.showQueue();
}
}
执行结果: