Article Directory
3. Queue
1 Introduction
- A queue is an ordered list, which can be implemented by an array or a linked list
- Follow the principle of first in first out.
- As shown in the figure below: when saving data, the front remains unchanged, and the rear changes; when fetching data, the rear position remains unchanged, and the front position changes
2. Icon
Found in the picture site
- rear: the tail of the queue
- front: the head of the data
3. Array implements queue
the code
package 二__队列;
/*
队列
场景:排队
介绍:先进先出
*/
import java.util.Queue;
public class Test {
public static void main(String[] args) {
test1();
}
// 数组队列模型
public static void test1() {
ArrayQueue arrayQueue = new ArrayQueue(10);
arrayQueue.add(1);
arrayQueue.add(2);
arrayQueue.add(3);
arrayQueue.add(4);
arrayQueue.add(5);
arrayQueue.add(6);
arrayQueue.add(7);
arrayQueue.add(8);
arrayQueue.add(9);
arrayQueue.add(10);
arrayQueue.add(11);
arrayQueue.showQueue();
System.out.println("头部数据:"+arrayQueue.headQueue());
}
}
// 数组队列
class ArrayQueue {
private int maxSize; // 最大容量
private int front; // 队列头
private int rear; // 队列尾
private int[] arr; // 用来存储数据
// 创建队列的构造器
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.arr = new int[maxSize];
this.front = -1; // 指向队列头的前一个位置
this.rear = -1;
}
public boolean isFull() {
return rear == maxSize - 1;
}
public boolean isEmpty() {
return front == rear;
}
// 添加
public void add(int n) {
// 判断是否满
if (isFull()) {
System.out.println("队列满,不可以添加数据");
return;
}
// 尾部后移一位
rear++;
arr[rear] = n;
}
// 获取
public int poll() {
// 返回头部第一个
if (isEmpty()) {
System.out.println("队列为空");
return -1;
}
front++;
return arr[front];
}
//显示所有数据
public void showQueue(){
if(isEmpty()){
System.out.println("队列为空");
return;
}
for (int i : arr) {
if(i != 0) System.out.println(i);
}
}
// 显示队列头数据
public int headQueue(){
if(isEmpty()){
System.out.println("队列为空");
return -1;
}
return arr[front+1];
}
}
Review code
/*
队列基本要求:
1. 先进先出
2. rear 表示尾部
3. front 表示头部
4. array 表示存储数据的数组
1. 每添加一个数据 rear+1;
2. 每取出一个数据 front+1;
*/
// 数组队列
@Data
class TestArrayQueue{
private int maxSize;
private int rear ;
private int front ;
private int[] array;
public TestArrayQueue(int size){
this.maxSize = size;
array = new int[maxSize];
rear = -1;
front = -1;
}
// 判断是否已满
public boolean isFull(){
return rear-front == maxSize;
}
// 判断是否为空
public boolean isEmpty(){
return rear == front;
}
// 存储数据
public void add(int value){
if(isFull()){
throw new RuntimeException("队列已满");
}
rear ++;
array[rear] = value;
}
// 取出数据
public int get(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
front ++;
int value = array[front];
array[front] = 0;
return value;
}
// 打印所有数据
public void printAll(){
System.out.println(Arrays.toString(array));
}
}
// 测试 数组队列
public static void testArrayQueue(){
TestArrayQueue testArrayQueue = new TestArrayQueue(5);
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("-------------------------------------");
System.out.println("1) 添加数据");
System.out.println("2) 获取数据");
System.out.println("3) 打印所有数据");
String s = scanner.nextLine();
switch (s){
case "1":{
System.out.print("输入数据:___");
int i = scanner.nextInt();
testArrayQueue.add(i);
System.out.println("输入成功");
System.out.println("---------------");
continue;
}
case "2":{
System.out.println(testArrayQueue.get());
continue;
}
case "3":{
testArrayQueue.printAll();
continue;
}
}
}
}
4. Arrays simulate ring queues
-
question
Arrays cannot be reused, one-time
Use algorithm optimization to improve into a ring queue, use modulo algorithm to optimize
-
analyze
-
front now points to the first element of the queue (was pointing to the previous element)
-
rear meaning adjustment: rear points to the position after the last element of the queue. Make a space to make a promise.
It is convenient to judge whether front and rear are equal: the initial value of rear is 0.
-
When the queue is full, the condition is (rear+1)%maxSize = front【full】
-
When the queue is empty, rear == front(0) [empty]
-
-
the code
the code
package 二__队列;
/*
Date:2022/4/6
author: Blue Friday
describe: //todo
*/
public class Test2 {
public static void main(String[] args) {
CircleArrayQueue circleArrayQueue = new CircleArrayQueue(4);
circleArrayQueue.add(1);
circleArrayQueue.add(2);
circleArrayQueue.add(3);
circleArrayQueue.add(4);
System.out.println(circleArrayQueue.poll());
System.out.println(circleArrayQueue.poll());
System.out.println(circleArrayQueue.poll());
System.out.println(circleArrayQueue.poll());
// System.out.println(circleArrayQueue.poll());
circleArrayQueue.add(60);
System.out.println(circleArrayQueue.poll());
}
}
// 环形队列
class CircleArrayQueue {
private int maxSize; // 最大容量
private int front; // 队列头
private int rear; // 队列尾
private int[] arr; // 用来存储数据
// 创建队列的构造器
public CircleArrayQueue(int arrmaxSize) {
maxSize = arrmaxSize +1;
this.arr = new int[maxSize];
this.front = 0; // 指向队列头的前一个位置
this.rear = 0; // 指向队列尾
}
// 满队列条件
public boolean isFull() {
return (rear + 1 )%maxSize == front;
}
// 判断队列是否为空
public boolean isEmpty() {
return rear == front;
}
// 添加
public void add(int n) {
// 判断是否满
if (isFull()) {
System.out.println("队列满");
return;
}
arr[rear] = n;
// 将rear后移,这里需要取模,
rear = (rear + 1)%maxSize;
}
// 获取
public int poll() {
if(isEmpty()){
throw new RuntimeException("队列空");
}
int value = arr[front];
front = (front +1) % maxSize;
return value;
}
//显示所有数据
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return;
}
// 遍历多少元素
// 有效数据个数
int size = size();
for (int i = 0; i < front + size ; i++) {
System.out.println(i % maxSize+": "+arr[i % maxSize]);
}
}
// 显示队列头数据
public int headQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return -1;
}
return arr[front];
}
// 队列有效个数
public int size(){
return (rear + maxSize - front)%maxSize;
}
}
Review code
// 测试环形数组
public static void testCircularQueueC() {
TestCircularQueue testCircularQueue = new TestCircularQueue(5);
Scanner scanner = new Scanner(System.in);
while (true) {
try {
System.out.println("-------------------------------------");
System.out.println("1) 添加数据");
System.out.println("2) 获取数据");
System.out.println("3) 打印所有数据");
String s = scanner.nextLine();
switch (s) {
case "1": {
System.out.print("输入数据:___");
int i = scanner.nextInt();
testCircularQueue.add(i);
System.out.println("输入成功");
System.out.println("---------------");
continue;
}
case "2": {
System.out.println(testCircularQueue.get());
continue;
}
case "3": {
testCircularQueue.printArray();
continue;
}
}
}catch (Exception e){
System.out.println(e.getMessage());
}
}
}
// 环形数组队列
@Data
class TestCircularQueue {
/*
1. 修改定义 rear 初始 = 0; front = 0;
2. 队列满:( rear + 1 )%maxSize = front;
3. 队列空:rear == front
举例:
1. 不修改定义
- 初始化数组(指向前一个元素): rear = -1 ;front = -1;maxSize = 3;
队列满:rear - front == maxSize;
队列空:rear == front
- 添加数据 array = [1,2,3];rear=2;front=-1;
队列满:true --> 2 -- 1 = 3
队列空:false --> 2 == -1
- 取出一个数据 array = [0,2,3];rear=2;front=0;
队列满:false --> 2 - 0 = 3
队列空:false --> 2 == 0
- 取出所有数据 array = [0,0,0];rear=2;front=2;
队列满:false --> 2 - 2 = 3
队列空:true --> 2 == 2
- 继续添加数据 array=[0,2,3] --> [1,2,3]
rear=0;front=0;
队列满:false --> 0 - 0 = 3
队列空:true --> 0 == 0 (条件错误)
2. 修改定义
*/
private int maxSize;
private int rear;
private int front;
private int[] array;
public TestCircularQueue(int size) {
this.maxSize = size;
array = new int[maxSize];
}
// 判断是否已满
public boolean isFull() {
return (rear + 1) % maxSize == front;
}
// 判断是否为空
public boolean isEmpty() {
return rear == front;
}
// 存储数据
public void add(int value) {
if (isFull()) {
throw new RuntimeException("队列已满");
}
array[rear] = value;
rear = (rear + 1) % maxSize;
}
// 取出数据
public int get() {
if (isEmpty()) {
throw new RuntimeException("队列为空");
}
int value = array[front];
array[front] = 0;
front = (front + 1) % maxSize;
return value;
}
// 打印所有数据
public void printArray() {
System.out.println(Arrays.toString(array));
}
}
```# 三、队列
## 1. 介绍
1. 队列是一个有序列表,可以通过数组或者链表实现
2. 遵循先入先出的原则。
3. 如下图:存入数据时,front不变,rear变化;取数据时,rear位置不变,front的位置变化
## 2. 图示
图片站内找的![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hwV4khKf-1649303240655)(https://secure2.wostatic.cn/static/nQwtdspuVpA6vWQBFmA1Aa/image.png)\]](https://img-blog.csdnimg.cn/3337adbcd1874b0cac88c51c594b9e8d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ZW_5rO96ZuF576O5L2g6ICB5amG,size_14,color_FFFFFF,t_70,g_se,x_16)
- rear:队列的尾部
- front:数据的头部
## 3. 数组实现队列
- 代码
```java
package 二__队列;
/*
队列
场景:排队
介绍:先进先出
*/
import java.util.Queue;
public class Test {
public static void main(String[] args) {
test1();
}
// 数组队列模型
public static void test1() {
ArrayQueue arrayQueue = new ArrayQueue(10);
arrayQueue.add(1);
arrayQueue.add(2);
arrayQueue.add(3);
arrayQueue.add(4);
arrayQueue.add(5);
arrayQueue.add(6);
arrayQueue.add(7);
arrayQueue.add(8);
arrayQueue.add(9);
arrayQueue.add(10);
arrayQueue.add(11);
arrayQueue.showQueue();
System.out.println("头部数据:"+arrayQueue.headQueue());
}
}
// 数组队列
class ArrayQueue {
private int maxSize; // 最大容量
private int front; // 队列头
private int rear; // 队列尾
private int[] arr; // 用来存储数据
// 创建队列的构造器
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.arr = new int[maxSize];
this.front = -1; // 指向队列头的前一个位置
this.rear = -1;
}
public boolean isFull() {
return rear == maxSize - 1;
}
public boolean isEmpty() {
return front == rear;
}
// 添加
public void add(int n) {
// 判断是否满
if (isFull()) {
System.out.println("队列满,不可以添加数据");
return;
}
// 尾部后移一位
rear++;
arr[rear] = n;
}
// 获取
public int poll() {
// 返回头部第一个
if (isEmpty()) {
System.out.println("队列为空");
return -1;
}
front++;
return arr[front];
}
//显示所有数据
public void showQueue(){
if(isEmpty()){
System.out.println("队列为空");
return;
}
for (int i : arr) {
if(i != 0) System.out.println(i);
}
}
// 显示队列头数据
public int headQueue(){
if(isEmpty()){
System.out.println("队列为空");
return -1;
}
return arr[front+1];
}
}
- Review code
/*
队列基本要求:
1. 先进先出
2. rear 表示尾部
3. front 表示头部
4. array 表示存储数据的数组
1. 每添加一个数据 rear+1;
2. 每取出一个数据 front+1;
*/
// 数组队列
@Data
class TestArrayQueue{
private int maxSize;
private int rear ;
private int front ;
private int[] array;
public TestArrayQueue(int size){
this.maxSize = size;
array = new int[maxSize];
rear = -1;
front = -1;
}
// 判断是否已满
public boolean isFull(){
return rear-front == maxSize;
}
// 判断是否为空
public boolean isEmpty(){
return rear == front;
}
// 存储数据
public void add(int value){
if(isFull()){
throw new RuntimeException("队列已满");
}
rear ++;
array[rear] = value;
}
// 取出数据
public int get(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
front ++;
int value = array[front];
array[front] = 0;
return value;
}
// 打印所有数据
public void printAll(){
System.out.println(Arrays.toString(array));
}
}
// 测试 数组队列
public static void testArrayQueue(){
TestArrayQueue testArrayQueue = new TestArrayQueue(5);
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("-------------------------------------");
System.out.println("1) 添加数据");
System.out.println("2) 获取数据");
System.out.println("3) 打印所有数据");
String s = scanner.nextLine();
switch (s){
case "1":{
System.out.print("输入数据:___");
int i = scanner.nextInt();
testArrayQueue.add(i);
System.out.println("输入成功");
System.out.println("---------------");
continue;
}
case "2":{
System.out.println(testArrayQueue.get());
continue;
}
case "3":{
testArrayQueue.printAll();
continue;
}
}
}
}
4. Arrays simulate ring queues
-
question
Arrays cannot be reused, one-time
Use algorithm optimization to improve into a ring queue, use modulo algorithm to optimize
-
analyze
-
front now points to the first element of the queue (was pointing to the previous element)
-
rear meaning adjustment: rear points to the position after the last element of the queue. Make a space to make a promise.
It is convenient to judge whether front and rear are equal: the initial value of rear is 0.
-
When the queue is full, the condition is (rear+1)%maxSize = front【full】
-
When the queue is empty, rear == front(0) [empty]
-
-
the code
the code
package 二__队列;
/*
Date:2022/4/6
author: Blue Friday
describe: //todo
*/
public class Test2 {
public static void main(String[] args) {
CircleArrayQueue circleArrayQueue = new CircleArrayQueue(4);
circleArrayQueue.add(1);
circleArrayQueue.add(2);
circleArrayQueue.add(3);
circleArrayQueue.add(4);
System.out.println(circleArrayQueue.poll());
System.out.println(circleArrayQueue.poll());
System.out.println(circleArrayQueue.poll());
System.out.println(circleArrayQueue.poll());
// System.out.println(circleArrayQueue.poll());
circleArrayQueue.add(60);
System.out.println(circleArrayQueue.poll());
}
}
// 环形队列
class CircleArrayQueue {
private int maxSize; // 最大容量
private int front; // 队列头
private int rear; // 队列尾
private int[] arr; // 用来存储数据
// 创建队列的构造器
public CircleArrayQueue(int arrmaxSize) {
maxSize = arrmaxSize +1;
this.arr = new int[maxSize];
this.front = 0; // 指向队列头的前一个位置
this.rear = 0; // 指向队列尾
}
// 满队列条件
public boolean isFull() {
return (rear + 1 )%maxSize == front;
}
// 判断队列是否为空
public boolean isEmpty() {
return rear == front;
}
// 添加
public void add(int n) {
// 判断是否满
if (isFull()) {
System.out.println("队列满");
return;
}
arr[rear] = n;
// 将rear后移,这里需要取模,
rear = (rear + 1)%maxSize;
}
// 获取
public int poll() {
if(isEmpty()){
throw new RuntimeException("队列空");
}
int value = arr[front];
front = (front +1) % maxSize;
return value;
}
//显示所有数据
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return;
}
// 遍历多少元素
// 有效数据个数
int size = size();
for (int i = 0; i < front + size ; i++) {
System.out.println(i % maxSize+": "+arr[i % maxSize]);
}
}
// 显示队列头数据
public int headQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return -1;
}
return arr[front];
}
// 队列有效个数
public int size(){
return (rear + maxSize - front)%maxSize;
}
}
Review code
// 测试环形数组
public static void testCircularQueueC() {
TestCircularQueue testCircularQueue = new TestCircularQueue(5);
Scanner scanner = new Scanner(System.in);
while (true) {
try {
System.out.println("-------------------------------------");
System.out.println("1) 添加数据");
System.out.println("2) 获取数据");
System.out.println("3) 打印所有数据");
String s = scanner.nextLine();
switch (s) {
case "1": {
System.out.print("输入数据:___");
int i = scanner.nextInt();
testCircularQueue.add(i);
System.out.println("输入成功");
System.out.println("---------------");
continue;
}
case "2": {
System.out.println(testCircularQueue.get());
continue;
}
case "3": {
testCircularQueue.printArray();
continue;
}
}
}catch (Exception e){
System.out.println(e.getMessage());
}
}
}
// 环形数组队列
@Data
class TestCircularQueue {
/*
1. 修改定义 rear 初始 = 0; front = 0;
2. 队列满:( rear + 1 )%maxSize = front;
3. 队列空:rear == front
举例:
1. 不修改定义
- 初始化数组(指向前一个元素): rear = -1 ;front = -1;maxSize = 3;
队列满:rear - front == maxSize;
队列空:rear == front
- 添加数据 array = [1,2,3];rear=2;front=-1;
队列满:true --> 2 -- 1 = 3
队列空:false --> 2 == -1
- 取出一个数据 array = [0,2,3];rear=2;front=0;
队列满:false --> 2 - 0 = 3
队列空:false --> 2 == 0
- 取出所有数据 array = [0,0,0];rear=2;front=2;
队列满:false --> 2 - 2 = 3
队列空:true --> 2 == 2
- 继续添加数据 array=[0,2,3] --> [1,2,3]
rear=0;front=0;
队列满:false --> 0 - 0 = 3
队列空:true --> 0 == 0 (条件错误)
2. 修改定义
*/
private int maxSize;
private int rear;
private int front;
private int[] array;
public TestCircularQueue(int size) {
this.maxSize = size;
array = new int[maxSize];
}
// 判断是否已满
public boolean isFull() {
return (rear + 1) % maxSize == front;
}
// 判断是否为空
public boolean isEmpty() {
return rear == front;
}
// 存储数据
public void add(int value) {
if (isFull()) {
throw new RuntimeException("队列已满");
}
array[rear] = value;
rear = (rear + 1) % maxSize;
}
// 取出数据
public int get() {
if (isEmpty()) {
throw new RuntimeException("队列为空");
}
int value = array[front];
array[front] = 0;
front = (front + 1) % maxSize;
return value;
}
// 打印所有数据
public void printArray() {
System.out.println(Arrays.toString(array));
}
}