1)队列是一个有序列表,可以用数组或者链表实现
2)遵循先入先出的原则
使用数组实现队列

示意图
front:为对首标志,表示队列数组队首的下标-1
rear:为对尾标志,表示队列数组队尾的下标
public class ArrayQueueDemo {public static void main(String[] args) {//创建队列ArrayQueue arrayQueue = new ArrayQueue(3);Scanner scanner = new Scanner(System.in);boolean loop = true;while (loop) {System.out.println("请输入:");System.out.println("1:展示数据");System.out.println("2:查看队首");System.out.println("3:添加数据");System.out.println("4:取出数据");System.out.println("5:退出");int key = scanner.nextInt();switch (key) {case 1:arrayQueue.showQueue();break;case 2:arrayQueue.peek();break;case 3:System.out.println("输入要添加的数据:");int n = scanner.nextInt();arrayQueue.addQueue(n);break;case 4:try{int data = arrayQueue.getQueue();System.out.println("取出数据:"+data);}catch (Exception e){String message = e.getMessage();System.out.println(message);}break;case 5:loop = false;break;default:System.out.println("输入有误");break;}}}}/*** 数组队列自定义类*/class ArrayQueue{private int maxSize; //表示数组最大容量private int front; //指向队首private int rear; //指向队尾private int[] arr; //队列模拟数组public ArrayQueue(int maxSize){this.maxSize = maxSize;arr = new int[maxSize];front = -1; //指向队列前一个位置rear = -1; //指向队尾}//判断队列是否满public boolean isFull(){//队尾下标等于最大容量-1return rear == maxSize - 1;}//判断是否为空public boolean isEmpty(){return front == rear;}//添加数据public boolean addQueue(int n){//判断队列是否满if (isFull()){System.out.println("队列已满");return false;}rear++;arr[rear] = n;return true;}//取出数据public int getQueue(){//判断是否空if(isEmpty()){throw new RuntimeException("队列为空");}front++;return arr[front];}//显示队列的所有数据public void showQueue() {if (isEmpty()){System.out.println("队列空");return;}for(int i=0;i<arr.length;i++){System.out.println("arr["+i+"]="+arr[i]);}}//显示队列头数据public void peek(){//判断是否空if (isEmpty()) {System.out.println("队列空");return;}System.out.println(arr[front+1]);}}
以上实现存在问题:无法反复使用,因为队列中的下标会一直往前移动,导致队尾标志rear达到maxSize后无法再添加数据,而前面的空间由于front队首标志变大之后也无法继续使用
问题分析:
1)目前数组使用一次后就不能再用,没有达到复用的效果
2)将这个数组使用算法,改进成环形队列,使用取模:%
改写环形队列
思路分析:
1)front变量含义调整为:front指向队列的第一个元素
2)rear变量含义调整为:指向最后一个元素的后一个空的位置
3)队列满条件:(rear+1)%maxSize == front
4)队列空条件:rear == front
5)队列有效个数:(rear+maxSize-front)%maxSize //rear=1 front=0

package com.cwl;/*** @Author Administrator* @Date 2021/2/19 0019 9:09* @Version 1.0*/public class CircleArrayQueueDemo {public static void main(String[] args) {CircleArrayQueue circleArrayQueue = new CircleArrayQueue(6);circleArrayQueue.offer(0);circleArrayQueue.offer(1);circleArrayQueue.offer(2);circleArrayQueue.offer(3);circleArrayQueue.offer(4);circleArrayQueue.poll();//front=1circleArrayQueue.offer(5);//rear=0circleArrayQueue.poll();//front=2circleArrayQueue.offer(6);//rear=1circleArrayQueue.poll();//front=3circleArrayQueue.offer(7);//rear=2circleArrayQueue.poll();//front=4circleArrayQueue.offer(8);//rear=3int i = circleArrayQueue.hasElement();System.out.println("有效元素:"+i);circleArrayQueue.look();}}class CircleArrayQueue{private int maxSize; //最大容量,预留一个位置为空,避免前后端指针重合不易判断满和空private int rear; //队列后端指针,指向后端 + 1的位置private int front;//队列前端,指向头部private int[] arr;//队列,存放数据//构造器初始化数组容量public CircleArrayQueue(int maxSize){this.maxSize = maxSize;arr = new int[maxSize];}//判断满public boolean isFull(){return (rear + 1) % maxSize == front;}//判断空public boolean isEmpty(){return front == rear;}//返回有效数据个数,最大不超过maxSize-1public int hasElement(){return (rear + maxSize - front) % maxSize;}//入队,先判断是否满,若rear达到最大值maxSize将其取模为0public void offer(int val){if (isFull()){System.out.println("满");return;}arr[rear] = val;rear ++;if (rear == maxSize){rear = 0;}}//出队,先判断是否空,若front达到最大值maxSize将其取模为0public int poll(){if(isEmpty()){throw new RuntimeException("空");}int temp = arr[front];front ++;if (front == maxSize){front = 0;}return temp;}//查看队列头,先判断是否空,返回队列头的值,不会出队public int peek(){if (isEmpty()){throw new RuntimeException("空");}return arr[front];}//查看队列所有(有效值),当队列满时,实际上只有maxSize-1个有效值,从front开始遍历,大于等于maxSize时取模public void look(){if (isEmpty()){System.out.println("空");}for (int i = front;i < front + hasElement();i++){System.out.println("arr[" + i % maxSize+"]=" + arr[i % maxSize]);}}}
