java数据结构之队列,Java数据结构之队列(Queue)

本文详细介绍了如何使用数组来模拟队列,并探讨了队列的先入先出原则。首先,解释了数组模拟普通队列的方法,包括队列满和队列空的判断条件。接着,讨论了数组模拟环形队列的优化方案,调整了front和rear的含义以避免数组越界问题,并给出了队列满和队列空的新判断条件。此外,还提供了具体的代码实现,展示了添加、移除元素以及检查队列状态的操作。
摘要由CSDN通过智能技术生成

1.使用场景

银行排队的案例:

6299340202324751ce142b49d8aa3c56.png

2.队列介绍

队列是一个有序列表,可以用数组或是链表来实现。

遵循先入先出的原则:

先存入队列的数据,要先取出。

后存入的要后取出

示意图:(使用数组模拟队列示意图)

0876653c6cf93fb1ef82f809ecfa0b8b.png

3.实现方式1:数组模拟队列

思路分析

队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图, 其中 maxSize 是该队列的最大容量。

f4d8c7172248ce99b4ef2181bb52f6ff.png

front 是队列最前元素之前一个位置【不含最前】

rear 是队列最后元素 【含最后】

插入队列,判断是否已满,将尾指针往后移:rear++,然后插入arr[rear]

移出队列,判断是否为空,将前指针往后移:front++,然后移出arr[front]

队列为空判断条件:当front == rear 【空】

队列是否满判断条件:rear == maxSize - 1【队列满】

代码实现

c7dc3dd574b999619d54a84dcd103ac2793.jpg

85fa66058333e0fad3d5f59bf07bc5b8d2a.jpg

//使用数组模拟队列-编写一个ArrayQueue类

classArrayQueue {private int maxSize; //表示数组的最大容量

private int front; //队列头

private int rear; //队列尾

private int[] arr; //该数据用于存放数据, 模拟队列//创建队列的构造器

public ArrayQueue(intarrMaxSize) {

maxSize=arrMaxSize;

arr= new int[maxSize];

front= -1; //指向队列头部,分析出front是指向队列头的前一个位置.

rear = -1; //指向队列尾,指向队列尾的数据(即就是队列最后一个数据)

}//判断队列是否满

public booleanisFull() {return rear == maxSize - 1;

}//判断队列是否为空

public booleanisEmpty() {return rear ==front;

}//添加数据到队列

public void addQueue(intn) {//判断队列是否满

if(isFull()) {

System.out.println("队列满,不能加入数据~");return;

}

rear++; //让rear 后移

arr[rear] =n;

}//获取队列的数据, 出队列

public intgetQueue() {//判断队列是否空

if(isEmpty()) {//通过抛出异常

throw new RuntimeException("队列空,不能取数据");

}

front++; //front后移

returnarr[front];

}//显示队列的所有数据

public voidshowQueue() {//遍历

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 intheadQueue() {//判断

if(isEmpty()) {throw new RuntimeException("队列空的,没有数据~~");

}return arr[front + 1];

}

}

View Code

出现问题

目前数组不能复用,用一次就用不了了

优化方式:将数组模拟成环形队列

4. 数组模拟环形队列

思路:

1.front变量的含义做调整:front指向队列的第一个元素,即arr[front]就是队列的第一个元素

2.rear变量的含义做调整:rear指向队列的最后一个元素的后一个元素,因为希望空出一个空间作为约定(队列实际容量=maxSize-1,理解为防止指向超出数组范围的地方报错)。

3.当队列满时,条件是:(rear + 1) % maxSize == front [满]

4.当队列空时,条件是:rear == front [空]

5.队列中有效数据的个数:(rear + maxSize - front) % maxSize

6.插入队列时,判断队满,先插入队列arr[rear],然后rear++

7.移出队列时,判断队空,先移出队列arr[front],然后front++

代码实现

739bbaf20c2d5d6aef7aca5f43fe8f1c6d8.jpg

03279c3064901162db303c883e3f582e4fc.jpg

classCircleArray {private int maxSize; //表示数组的最大容量//front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素//front 的初始值 = 0

private intfront;//rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.//rear 的初始值 = 0

private int rear; //队列尾

private int[] arr; //该数据用于存放数据, 模拟队列

public CircleArray(intarrMaxSize) {

maxSize=arrMaxSize;

arr= new int[maxSize];

}//判断队列是否满

public booleanisFull() {return (rear + 1) % maxSize ==front;

}//判断队列是否为空

public booleanisEmpty() {return rear ==front;

}//添加数据到队列

public void addQueue(intn) {//判断队列是否满

if(isFull()) {

System.out.println("队列满,不能加入数据~");return;

}//直接将数据加入

arr[rear] =n;//将 rear 后移, 这里必须考虑取模

rear = (rear + 1) %maxSize;

}//获取队列的数据, 出队列

public intgetQueue() {//判断队列是否空

if(isEmpty()) {//通过抛出异常

throw new RuntimeException("队列空,不能取数据");

}//这里需要分析出 front是指向队列的第一个元素//1. 先把 front 对应的值保留到一个临时变量//2. 将 front 后移, 考虑取模//3. 将临时保存的变量返回

int value =arr[front];

front= (front + 1) %maxSize;returnvalue;

}//显示队列的所有数据

public voidshowQueue() {//遍历

if(isEmpty()) {

System.out.println("队列空的,没有数据~~");return;

}//思路:从front开始遍历,遍历多少个元素//动脑筋

for (int i = front; i < front + size() ; i++) {

System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i %maxSize]);

}

}//求出当前队列有效数据的个数

public intsize() {//rear = 2//front = 1//maxSize = 3

return (rear + maxSize - front) %maxSize;

}//显示队列的头数据, 注意不是取出数据

public intheadQueue() {//判断

if(isEmpty()) {throw new RuntimeException("队列空的,没有数据~~");

}returnarr[front];

}

}

View Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值