java数据结构循环队列的空满判断及长度计算

网友投稿 357 2022-07-26


目录一、假溢出二、循环队列判断是空是满三、循环队列的长度计算四、代码实现

在上一章中,使用了数组模拟了队列。但是留下的问题是,把数据取完后,再往里加数据就不行了。

一、假溢出

这是因为数组的末尾已经被占用了,入队会继续在数组后面增加,于是产生数组越界。但是实际上,数组里是有空闲位置的,这种也可以叫“假溢出”。

为了解决“假溢出”的问题,于是乎有了循环队列。

既然数组后面满了,头部有空,那继续加进来的元素从头开始放即可。

接着上图,这时候有a6入队,于是rear的下标指向a6的下一个元素位置,看起来没什么问题。

但是继续有新的元素a7入队的时候,因为front一直没变,这时候rear指针跟front就重合了,也就是说此时front=rear。

可是在上一章的代码里,我们是用front=rear来判断是否为空数组的。

// 判断队列是否为空

public boolean isEmpty() {

return rear == front;

}

现在是相等了,条件满足,但是数组是满的。

二、循环队列判断是空是满

这种情况看起来确实比较辣手,那如果不让这种情况出现不就可以了么?

假设,我们让数组始终保留一个元素空间,也就是让rear指向队列中最后一个元素的后一个位置。比如,当a6放入之后,此时就当做队列已经满了,这样的话就不会出现上述的情况了。

为了实现这种思路,front也需要做调整。在上一章中,front初始位置是指在了队头元素的前一个,现在我们让它就指在第一个元素。

队列的最大尺寸还是maxSize,那么,现在判断队列满的条件就可以是这样:

(rear+1)%maxSize = front

验证一下,下面的2种队列满情况:

左图:队列中,maxSize=5,front=0,rear=4,判断(4+1)% 5=0=front,队列已满

右图:队列中,maxSize=5,front=2,rear=1,判断(1+1)% 5=2=front,队列已满

继续验证一下,队列没满的情况:

队列中,maxSize=5,front=2,rear=0,判断(0+1)% 5=1≠front,队列未满

三、循环队列的长度计算

队列的长度,也就是说队列中实际存了多少个元素。

此时需要考虑rear与front之间的三种情况:

rear=frontrear>frontrear

第一种自然都清楚,队列为空。

第二种,rear>front,此时队列的长度为:rear-front

第三种,rear

所以队列长度的通用计算公式为:

(rear-front+maxSize)% maxSize

四、代码实现

既然现在队列是满是空的判断条件有了,队列长度也能计算出来了,那么代码就好改造了(基于上一章),变成循环队列。

package circle;

import java.util.Scanner;

public class CircleArrayQueue {

public static void main(String[] args) {

System.out.println("-----测试循环队列-----http://");

// 创建一个队列

CircleArray circleArray = new CircleArray(4);

char key = ' '; //接受用户输入

Scanner scanner = 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 = scanner.next().charAt(0); // 接收一个字符

switch (key) {

case 's':

circleArray.showQueue();

break;

case 'a':

SysjIdpFtem.out.println("请要添加的数");

int value = scanner.nextInt();

circleArray.addQueue(value);

break;

case 'g':

try {

int res = circleArray.getQueue();

System.out.printf("取出的数据是:%d", res);

} catch (Exception e) {

System.out.println(e.getMessage());

}

break;

case 'h':

try {

int headValue = circleArray.showHeadQueue();

System.out.printf("队首数据是:%d", headValue);

} catch (Exception e) {

System.out.println(e.getMessage());

}

break;

case 'e':

scanner.close();

loop = false;

break;

}

}

System.out.println("退出程序");

}

}

class CircleArray {

//表示数组最大容量

private int maxSize;

// 队列头,由之前调整为指向队列第一个元素

private int front;

// 队列尾,由之前调整为指向队列最后一个元素的后一个位置,为了空出一个元素位置

private int rear;

// 用于存放数据的数组

private int[] arr;

// 构造器

public CircleArray(int arrMaxSize) {

maxSize = arrMaxSize;

arr = new int[maxSize];

front = 0;

rear = 0;

}

// 判断队列是否已经存满

public boolean isFull() {

return (rear + 1) % maxSize == front;

}

// 判断队列是否为空

public boolean isEmpty() {

return rear == front;

}

// 添加数据到队列

public void addQueue(int num) {

// 判断队列是否满了

if (isFull()) {

System.out.println("队列已满,不可加入数据");

return;

}

arr[rear] = num;

// 将rear后移,要考虑取模

rear = (rear + 1) % maxSize;

}

// 拿出队列数据

public int getQueue() {

// 判断队列是否空

if (isEmpty()) {

// 抛出异常

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

}

int tempValue = arr[front];

front = (front + 1) % maxSize; //也要考虑取模,防止front不停的增加,导致越界

return tempValue;

}

// 显示队列所有数据

public void showQueue() {

// 遍历

if (isEmpty()) {

System.out.println("队列为空");

return;

}

// 从front开始遍历,遍历多少个实际存的元素即可

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

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

}

}

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

public int CircleQueueSize() {

return (rear - front + maxSize) % maxSize;

}

// 显示队里的队首数据

public int showHeadQueue() {

if (isEmpty()) {

// 抛出异常

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

}

return arr[front];

}

}

重点的改动在于取模。

以上就是java数据结构循环队列的空满判断及长度计算的详细内容,更多关于java循环队列空满判断长度计算的资料请关注我们其它相关文章!

第一种自然都清楚,队列为空。

第二种,rear>front,此时队列的长度为:rear-front

第三种,rear

所以队列长度的通用计算公式为:

(rear-front+maxSize)% maxSize

四、代码实现

既然现在队列是满是空的判断条件有了,队列长度也能计算出来了,那么代码就好改造了(基于上一章),变成循环队列。

package circle;

import java.util.Scanner;

public class CircleArrayQueue {

public static void main(String[] args) {

System.out.println("-----测试循环队列-----http://");

// 创建一个队列

CircleArray circleArray = new CircleArray(4);

char key = ' '; //接受用户输入

Scanner scanner = 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 = scanner.next().charAt(0); // 接收一个字符

switch (key) {

case 's':

circleArray.showQueue();

break;

case 'a':

SysjIdpFtem.out.println("请要添加的数");

int value = scanner.nextInt();

circleArray.addQueue(value);

break;

case 'g':

try {

int res = circleArray.getQueue();

System.out.printf("取出的数据是:%d", res);

} catch (Exception e) {

System.out.println(e.getMessage());

}

break;

case 'h':

try {

int headValue = circleArray.showHeadQueue();

System.out.printf("队首数据是:%d", headValue);

} catch (Exception e) {

System.out.println(e.getMessage());

}

break;

case 'e':

scanner.close();

loop = false;

break;

}

}

System.out.println("退出程序");

}

}

class CircleArray {

//表示数组最大容量

private int maxSize;

// 队列头,由之前调整为指向队列第一个元素

private int front;

// 队列尾,由之前调整为指向队列最后一个元素的后一个位置,为了空出一个元素位置

private int rear;

// 用于存放数据的数组

private int[] arr;

// 构造器

public CircleArray(int arrMaxSize) {

maxSize = arrMaxSize;

arr = new int[maxSize];

front = 0;

rear = 0;

}

// 判断队列是否已经存满

public boolean isFull() {

return (rear + 1) % maxSize == front;

}

// 判断队列是否为空

public boolean isEmpty() {

return rear == front;

}

// 添加数据到队列

public void addQueue(int num) {

// 判断队列是否满了

if (isFull()) {

System.out.println("队列已满,不可加入数据");

return;

}

arr[rear] = num;

// 将rear后移,要考虑取模

rear = (rear + 1) % maxSize;

}

// 拿出队列数据

public int getQueue() {

// 判断队列是否空

if (isEmpty()) {

// 抛出异常

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

}

int tempValue = arr[front];

front = (front + 1) % maxSize; //也要考虑取模,防止front不停的增加,导致越界

return tempValue;

}

// 显示队列所有数据

public void showQueue() {

// 遍历

if (isEmpty()) {

System.out.println("队列为空");

return;

}

// 从front开始遍历,遍历多少个实际存的元素即可

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

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

}

}

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

public int CircleQueueSize() {

return (rear - front + maxSize) % maxSize;

}

// 显示队里的队首数据

public int showHeadQueue() {

if (isEmpty()) {

// 抛出异常

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

}

return arr[front];

}

}

重点的改动在于取模。

以上就是java数据结构循环队列的空满判断及长度计算的详细内容,更多关于java循环队列空满判断长度计算的资料请关注我们其它相关文章!

所以队列长度的通用计算公式为:

(rear-front+maxSize)% maxSize

四、代码实现

既然现在队列是满是空的判断条件有了,队列长度也能计算出来了,那么代码就好改造了(基于上一章),变成循环队列。

package circle;

import java.util.Scanner;

public class CircleArrayQueue {

public static void main(String[] args) {

System.out.println("-----测试循环队列-----http://");

// 创建一个队列

CircleArray circleArray = new CircleArray(4);

char key = ' '; //接受用户输入

Scanner scanner = 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 = scanner.next().charAt(0); // 接收一个字符

switch (key) {

case 's':

circleArray.showQueue();

break;

case 'a':

SysjIdpFtem.out.println("请要添加的数");

int value = scanner.nextInt();

circleArray.addQueue(value);

break;

case 'g':

try {

int res = circleArray.getQueue();

System.out.printf("取出的数据是:%d", res);

} catch (Exception e) {

System.out.println(e.getMessage());

}

break;

case 'h':

try {

int headValue = circleArray.showHeadQueue();

System.out.printf("队首数据是:%d", headValue);

} catch (Exception e) {

System.out.println(e.getMessage());

}

break;

case 'e':

scanner.close();

loop = false;

break;

}

}

System.out.println("退出程序");

}

}

class CircleArray {

//表示数组最大容量

private int maxSize;

// 队列头,由之前调整为指向队列第一个元素

private int front;

// 队列尾,由之前调整为指向队列最后一个元素的后一个位置,为了空出一个元素位置

private int rear;

// 用于存放数据的数组

private int[] arr;

// 构造器

public CircleArray(int arrMaxSize) {

maxSize = arrMaxSize;

arr = new int[maxSize];

front = 0;

rear = 0;

}

// 判断队列是否已经存满

public boolean isFull() {

return (rear + 1) % maxSize == front;

}

// 判断队列是否为空

public boolean isEmpty() {

return rear == front;

}

// 添加数据到队列

public void addQueue(int num) {

// 判断队列是否满了

if (isFull()) {

System.out.println("队列已满,不可加入数据");

return;

}

arr[rear] = num;

// 将rear后移,要考虑取模

rear = (rear + 1) % maxSize;

}

// 拿出队列数据

public int getQueue() {

// 判断队列是否空

if (isEmpty()) {

// 抛出异常

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

}

int tempValue = arr[front];

front = (front + 1) % maxSize; //也要考虑取模,防止front不停的增加,导致越界

return tempValue;

}

// 显示队列所有数据

public void showQueue() {

// 遍历

if (isEmpty()) {

System.out.println("队列为空");

return;

}

// 从front开始遍历,遍历多少个实际存的元素即可

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

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

}

}

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

public int CircleQueueSize() {

return (rear - front + maxSize) % maxSize;

}

// 显示队里的队首数据

public int showHeadQueue() {

if (isEmpty()) {

// 抛出异常

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

}

return arr[front];

}

}

重点的改动在于取模。

以上就是java数据结构循环队列的空满判断及长度计算的详细内容,更多关于java循环队列空满判断长度计算的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java实现简单的客户信息管理系统
下一篇:Springboot实例讲解实现专业材料认证管理系统流程
相关文章

 发表评论

暂时没有评论,来抢沙发吧~