队列是一个有序列表,可以用数组或是链表来实现。
遵循先进先出的原则。
1、数组模拟队列思路
队列本身是有序队列,若用数组结构来存储队列的数据,则队列数据的声明如下图,其中maxSize是该队列的最大容量。
因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front 及 rear 分别记录队列前后端的下标,front 会随着数据输出而改变,如图所示:
当我们将数据存入队列时称为“addQueue”, addQueue 的处理需要有两个步骤: 思路分析
1)将尾针往后移: rear+1,当front == rear【空】
2)若尾指针 rear 小于最大下标 maxSize-1 ,则将数据存入rear若之的数组元素中,否则无法存入数据。rear ==maxSize - 1【队列满】
代码如下:
package com;import java.util.Scanner;public class ArrayQueueDemo {public static void main(String[] args) {ArrayQueue Queue = new ArrayQueue(3);char key = ' ';//接受用户输入Scanner scan = new Scanner(System.in);boolean loop = true;// 输出一个菜单while(loop){System.out.println("s(show): 显示队列");System.out.println("e(exit): 退出程序");System.out.println("a(add): 添加数据到队列");System.out.println("g(get): 从队列取出数据");System.out.println("h(head): 查看队列头的数据");key =scan.next().charAt(0);//接受一个字符switch (key){case 's':Queue.showQueue();break;case 'a':System.out.println("请输入一个数字");int value = scan.nextInt();Queue.addQueue(value);break;case 'g':try {int res = Queue.getQueue();System.out.printf("取出的数据是:%d\n",res);}catch (Exception e){System.out.println(e.getMessage());}break;case 'h':try {int res = Queue.headQueue();System.out.printf("队列头的数据是:%d\n",res);}catch (Exception e){System.out.println(e.getMessage());}break;case 'e':scan.close();loop = false;default:break;}}System.out.println("程序退出");}}class ArrayQueue{private int maxSize;//表示数组的最大容量private int front;// 队列头private int rear;// 队列尾private int[] arr;// 创建队列的构造器public ArrayQueue(int arrMaxSize){maxSize = arrMaxSize;arr = new int[arrMaxSize];front = -1; //指向队列头部,分析出front是指向队列头的前一个位置。rear = -1;// 指向队列尾,指向队列尾的数据(即就是队列最后一个数据)}// 判断队列数据是否满public boolean isFull(){return rear == maxSize - 1;}public void addQueue(int n){// 判断队列是否满if(isFull()){System.out.println("队列满,不能加入数据");return;}rear++;// 让rear后移arr[rear] = n;}// 判断是否为空public boolean isEmpty(){return rear == front;}// 获取队列数据public int getQueue(){if (isEmpty()){//通过抛出异常throw new RuntimeException("队列为空");}front++;// 将front后移return arr[front];}// 显示队列所有数据public void showQueue(){// 遍历if(isEmpty()){System.out.println("队列空的,没有数据~~~");return;}for (int i=0; i<arr.length;i++){System.out.printf("arr[%d]=%d\n", i, arr[i]);}}// 显示队列的头数据,注意不是取出数据public int headQueue(){//判断if(isEmpty()){throw new RuntimeException("队列为空");}return arr[front + 1];}}
注意:以上代码所实现的是一个一次性队列,不能添加,因为头front和尾rear是往后移动的,所以要进行优化为环形队列,通过取模来实现。
2. 数组模拟环形队列


利用模运算:rear = rear + 1 ;if (rear==maxsize) rear = 0
可转化为:rear = (rear + 1)%maxsize
出队则:
front = (front +1)%maxsize
遍历:(rear+maxsize-front)%maxsize
public class ArrayQueueDemo2 {public static void main(String[] args) {circleArrayQueue Queue = new circleArrayQueue(4);char key = ' ';//接受用户输入Scanner scan = new Scanner(System.in);boolean loop = true;// 输出一个菜单while(loop){System.out.println("s(show): 显示队列");System.out.println("e(exit): 退出程序");System.out.println("a(add): 添加数据到队列");System.out.println("g(get): 从队列取出数据");System.out.println("h(head): 查看队列头的数据");key =scan.next().charAt(0);//接受一个字符switch (key){case 's':Queue.showQueue();break;case 'a':System.out.println("请输入一个数字");int value = scan.nextInt();Queue.addQueue(value);break;case 'g':try {int res = Queue.getQueue();System.out.printf("取出的数据是:%d\n",res);}catch (Exception e){System.out.println(e.getMessage());}break;case 'h':try {int res = Queue.headQueue();System.out.printf("队列头的数据是:%d\n",res);}catch (Exception e){System.out.println(e.getMessage());}break;case 'e':scan.close();loop = false;break;default:break;}}System.out.println("程序退出");}}class circleArrayQueue{private int maxSize;//表示数组的最大容量private int front;// 队列头private int rear;// 队列尾private int[] arr;// 创建队列的构造器public circleArrayQueue(int arrMaxSize){maxSize = arrMaxSize;arr = new int[arrMaxSize];//front = 0; //指向队列第一个元素,分析出front是指向队列头的前一个位置。//rear = 0;// 指向队列的最后一个位置,因为希望空出一个位置,指向队列尾的数据(即就是队列最后一个数据)}// 判断队列数据是否满public boolean isFull(){return (rear+1)%maxSize == front;}public void addQueue(int n){// 判断队列是否满if(isFull()){System.out.println("队列满,不能加入数据");return;}arr[rear] = n;rear = (rear+1)% maxSize;//考虑取模}// 判断是否为空public boolean isEmpty(){return rear == front;}// 获取队列数据public int getQueue(){if (isEmpty()){//通过抛出异常throw new RuntimeException("队列为空");}int value = arr[front];front = (front+1)%maxSize;// 将front后移,考虑取模return value;}// 显示队列所有数据public void showQueue(){// 遍历if(isEmpty()){System.out.println("队列空的,没有数据~~~");return;}for (int i=front; i<front + size();i++){System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);}}//求当前队列有效数据的个数public int size(){return (rear + maxSize - front) % maxSize;}// 显示队列的头数据,注意不是取出数据public int headQueue(){//判断if(isEmpty()){throw new RuntimeException("队列为空");}return arr[front];}}
