1. 使用场景
2. 基本介绍
- 队列是一个有序列表,可以用数组或是链表来实现。
- 遵循先入先出的原则。即先存入队列的数据,要先取出;后存入的要后取出。
3. 数组模拟队列
思路
队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图, 其中 maxSize 是该队列的最大容量。
因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front 和 rear 分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear 则是随着数据输入而改变,如图所示: 
当我们将数据存入队列时称为”addQueue“,addQueue的处理需要有两个步骤:思路分析
1) 将尾指针往后移:rear+1 , 当 front == rear 【空】
2) 若尾指针 rear小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。rear == maxSize - 1 [队列满]
不足
- 数组只能使用一次,当队列中的数据取出后,并不能复用之前用过的空间。
-
实现
添加元素,改变队尾指针 rear 的值;
- 移出元素,改变队头指针 front 的值;
- 其他操作不改变队头队尾的值,只在值基础上运算(取出队头为:front + 1)
数组队列
```java package com.zsy.datastructure.queue;
/**
- 使用数组模拟队列 *
@author zhangshuaiyin */ public class ArrayQueue {
/**
- 队列最大空间 / private int maxSize; /*
- front: 指向队列头的前一个位置,用于标识队列头
rear:指向队列尾部 */ private int front; private int rear; private int[] array;
public ArrayQueue(int arrayMaxSize) { maxSize = arrayMaxSize; array = new int[maxSize]; front = -1; rear = -1; }
/**
@return 判断队列是否为空 */ public boolean isEmpty() { return front == rear; }
/**
@return 判断队列是否已满 */ public boolean isFull() { return rear == maxSize - 1; }
/**
- 向队列添加元素 *
@param item 元素 */ public void add(int item) { if (isFull()) {
System.out.println("队列已满,不能添加元素~~");return;
} // rear 后移,新增一个存储空间 rear++; array[rear] = item; }
/**
- 出队 *
@return 头部数据 */ public int remove() { if (isEmpty()) {
throw new RuntimeException("队列为空不能取出数据!!");
} return array[++front]; }
/**
打印队列中的元素 */ public void show() { if (isEmpty()) {
System.out.println("The queue is empty.");return;
} for (int i = 0; i < array.length; i++) {
System.out.printf("arr[%d]=%d\n", i, array[i]);
} }
/**
- 打印队列头部元素
*/
public void head() {
if (isEmpty()) {
} System.out.println(“head: “ + array[front + 1]); } } ```System.out.println("The queue is empty.");return;
测试
```java package com.zsy.datastructure.queue;
import java.util.Scanner;
/**
@author zhangshuaiyin */ public class ArrayQueueTest { public static void main(String[] args) {
ArrayQueue queue = new ArrayQueue(3);// 接收输入字符char key;Scanner scanner = new Scanner(System.in);boolean loop = true;while (loop) {System.out.println("****************");System.out.println("s(show): 显示队列");System.out.println("a(add): 添加数据");System.out.println("g(get): 取出数据");System.out.println("h(head): 头部数据");System.out.println("按其他任意键退出...");System.out.println("****************");key = scanner.next().charAt(0);switch (key) {case 's':queue.show();break;case 'a':System.out.println("请输入要添加队列的数字:");int value = scanner.nextInt();queue.add(value);break;case 'g':try {System.out.println("取出的数据:" + queue.remove());} catch (Exception e) {System.out.println(e.getMessage());}break;case 'h':queue.head();break;default:scanner.close();loop = false;System.out.println("程序退出~~");break;}}
4. 数组循环队列
参考《大话数据结构》
思路分析
- front:指向队列的第一个元素,初始值为0;
- rear:指向队列最后一个元素的下一个位置,且该位置为保留位,不会被数据占用;
- 当队列满时,rear 应该指向 front 的前一个位置,即 (rear + 1) % maxSize == front();

- 当队列为空时,front == rear,即出队时 front 后移,当移动到保留位置,表示队列空;
- 队列中的元素个数:(rear - front + maxSize) % maxSize
- 当rear > front,长度为:rear - front


- 当 rear < front,长度为:(0 + rear) + (maxSize - front) = rear - front + maxSize
代码实现:
循环队列
package com.zsy.datastructure.queue;/*** 数组实现循环队列** @author zhangshuaiyin*/public class CircleArrayQueue {/*** 数组最大长度,因为rear预留位,队列长度会少一位*/private int maxSize;/*** front: 指向队列头一个元素*/private int front;/*** rear: 指向队列最后一个元素的下一个位置* rear指向的位置为保留位,不会被元素占用*/private int rear;private int[] array;public CircleArrayQueue(int arrayMaxSize) {this.maxSize = arrayMaxSize;array = new int[maxSize];this.front = this.rear = 0;}/*** @return 判断队列是否为空*/public boolean isEmpty() {return front == rear;}/*** @return 判断队列是否已满*/public boolean isFull() {return (rear + 1) % maxSize == front;}/*** 向队列添加元素** @param item 元素*/public void add(int item) {if (isFull()) {System.out.println("队列已满,不能添加元素~~");return;}array[rear] = item;// rear 后移,当移动到最后一个位置时,从 0 重新计数rear = (rear + 1) % maxSize;}/*** 出队** @return 头部数据*/public int remove() {if (isEmpty()) {throw new RuntimeException("队列为空不能取出数据!!");}// 取出数据为:array[front], 取出后 front 后移,当移动到最后一个位置时,从 0 重新计数int value = array[front];front = (front + 1) % maxSize;return value;}/*** 打印队列中的元素,从front开始到最后一个元素*/public void show() {if (isEmpty()) {System.out.println("The queue is empty.");return;}for (int i = front; i < front + size(); i++) {System.out.printf("arr[%d]=%d\n", i % maxSize, array[i % maxSize]);}}/*** 打印队列头部元素*/public void head() {if (isEmpty()) {System.out.println("The queue is empty.");return;}System.out.println("head: " + array[front]);}/*** @return 获取队列数据个数*/public int size() {return (rear - front + maxSize) % maxSize;}}
测试
参考:数组队列测试
package com.zsy.datastructure.queue;import java.util.Scanner;/*** @author zhangshuaiyin*/public class CircleArrayQueueTest {public static void main(String[] args) {CircleArrayQueue queue = new CircleArrayQueue(3);// 接收输入字符char key;Scanner scanner = new Scanner(System.in);boolean loop = true;while (loop) {System.out.println("****************");System.out.println("s(show): 显示队列");System.out.println("a(add): 添加数据");System.out.println("g(get): 取出数据");System.out.println("h(head): 头部数据");System.out.println("按其他任意键退出...");System.out.println("****************");key = scanner.next().charAt(0);switch (key) {case 's':queue.show();break;case 'a':System.out.println("请输入要添加队列的数字:");int value = scanner.nextInt();queue.add(value);break;case 'g':try {System.out.println("取出的数据:" + queue.remove());} catch (Exception e) {System.out.println(e.getMessage());}break;case 'h':queue.head();break;default:scanner.close();loop = false;System.out.println("程序退出~~");break;}}}}



