Java基础之数组模拟循环队列

 更新时间:2021年04月28日 10:06:08   作者:在下木子李  
这篇文章主要介绍了Java基础之数组模拟循环队列,文中有非常详细的代码示例,对正在学习java基础的小伙伴们也有非常好的帮助,需要的朋友可以参考下

一、队列简介

队列是一个有序列表,遵循“先入先出”的原则,即先存入队列的数据要先取出,后存入的数据后取出。

队列有两种存储表示,顺序表示和链式表示。顺序表示可以用数组来实现。

二、数组模拟队列

用数组模拟队列时,设两个值front=0,rear=0。front表示队列首部第一个数据所在位置,rear表示尾部最后一个数据的下一个位置。

将数据插入数组队列时(入队),从尾部进行插入,即array[rear] = value,同时rear后移,rear++。取出数据时(出队),从头部取出数据,value = array[front],同时front后移front++。

当front=0,rear=maxSize(数组的最大长度),队列满,不能再存入数据。

这时如果执行出队操作,又有空间可以存储,但继续插入数据,会出现溢出现象,即因数组越界而导致程序非法操作错误。而实际上空间并未占满,所以称这种现象为“假溢出”。这是由“队尾入队,队头出队”的限制操作所造成的。

如何解决“假溢出”的问题呢?

答案就是循环队列。

三、数组模拟循环队列

将顺序队列变为一个环状空间,front、rear和队列元素之间的关系不变,只是在循环队列中,front、rear依次后移加1的操作可用“模”运算来实现。

通过取模,front、rear就可以在顺序表空间内以头尾衔接的方式“循环”移动。

元素出队后,front = (front+1)%maxSize ;
元素入队后,rear = (rear+1)%maxSize 。

(maxSize为数组队列的最大长度)

例如,队列最大长度为4,当rear=3时,存入数据,array[3]=value,rear后移一位,如果没有取模运算,则rear=4,这时继续插入数据,array[4]越界。

如果进行取模运算,rear = (rear+1)%maxSize ,这时rear=0,rear又重新回到了0的位置。这样的运算,使得rear的值在0、1、2、3之间循环。

front的值同理。

写了这么多字,感觉还不如看代码来得更容易理解一点。

四、代码实现

数组模拟循环队列

package com.ArrayQueue;

import java.util.Scanner;

public class CircleArrayQueueDemo {
    public static void main(String args[]){
        int maxSize = 4;
        CircleArrayQueue queue = new CircleArrayQueue(maxSize);
        Scanner scanner = new Scanner(System.in);
        char key;
        boolean loop = true;
        while (loop) {
            //根据输入的不同字母,进行对应的操作
            System.out.println("a(add):添加一个数据");
            System.out.println("g(get):取出一个数据");
            System.out.println("h(head):展示头部数据");
            System.out.println("s(show):展示所有数据");
            System.out.println("q(quit):退出程序");
            //因为判满条件的缘故,队列的最大容量实为maxSize-1
            System.out.printf("(队列的最大容量为:%d)\n",maxSize-1);
            key = scanner.next().charAt(0);//接收一个字符
            try {
                switch (key) {
                    case 'a':
                        System.out.println("请输入一个数:");
                        int value = scanner.nextInt();
                        queue.addQueue(value);
                        System.out.println("数据添加成功。");
                        break;
                    case 'g':
                        System.out.printf("取出的数据为:%d\n", queue.getQueue());
                        break;
                    case 'h':
                        queue.headQueue();
                        break;
                    case 's':
                        queue.showQueue();
                        break;
                    case 'q':
                        scanner.close();
                        loop = false;
                        System.out.println("程序已退出。");
                        break;
                    default:
                        break;
                }
            } catch (RuntimeException e) {
                System.out.println(e.getMessage());
            }
        }
    }
}
/**
 * 队列的顺序表示
 * 数组模拟循环队列
 */
class CircleArrayQueue{
    private int maxSize;
    private int front;//指向头元素所在位置
    private int rear;//指向尾元素所在位置的下一个位置
    private int arr[];//存放数据的数组

    //构造器,传入数组最大容量值
    public CircleArrayQueue(int size){
        maxSize = size;
        front = 0;
        rear = 0;
        //虽然数组最大容量为maxSize,但实际用于存储的只有maxSize-1
        arr = new int[maxSize];
    }
    //判空条件:front == rear
    public boolean isEmpty(){
        return front == rear;
    }
    //判满条件:(rear+1)%maxSize == front
    public boolean isFull(){
        return (rear+1)%maxSize == front;
    }
    //添加数据,入队
    public void addQueue(int n){
        //判满
        checkFull();
        arr[rear] = n;
        rear = (rear+1)%maxSize;
    }
    //取出数据,出队
    public int getQueue(){
        //判空
        checkEmpty();
        int value = arr[front];
        front = (front+1)%maxSize;
        return value;
    }
    //队列中的有效值个数
    public int size(){
        return (rear-front+maxSize)%maxSize;
    }
    //展示队列的所有数据
    public void showQueue(){
        //判空
        checkEmpty();
        for(int i=front;i<front+size();i++){
            System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]);
        }
        System.out.printf("当前front=%d,rear=%d\n",front,rear);
    }
    //展示位于队列头部的元素值,不改变front的指向
    public void headQueue(){
        //判空
        checkEmpty();
        System.out.printf("头部数据是:%d\n",arr[front]);
    }
    //检测出队列为空时,打印当前front,rear的值,抛出异常
    public void checkEmpty(){
        if (isEmpty()) {
            System.out.printf("当前front=%d,rear=%d\n",front,rear);
            throw new RuntimeException("队列为空,不能取数据");
        }
    }
    //检测出队列满时,打印当前front,rear的值,抛出异常
    public void checkFull(){
        if(isFull()){
            System.out.printf("当前front=%d,rear=%d\n",front,rear);
            throw new RuntimeException("队列已满,不能添加数据");
        }
    }
}

五、运行结果


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

到此这篇关于Java基础之数组模拟循环队列的文章就介绍到这了,更多相关Java数组模拟循环队列内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis中orderBy(排序字段)和sort(排序方式)引起的bug及解决

    mybatis中orderBy(排序字段)和sort(排序方式)引起的bug及解决

    这篇文章主要介绍了mybatis中orderBy(排序字段)和sort(排序方式)引起的bug,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • spring boot中的条件装配bean的实现

    spring boot中的条件装配bean的实现

    这篇文章主要介绍了spring boot中的条件装配bean的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • maven项目打包上传到私有仓库

    maven项目打包上传到私有仓库

    在项目开发中通常会引用其他的jar,怎样把自己的项目做为一个jar包的形式发布到私服仓库中,本文就详细的介绍一下,感兴趣的可以了解一下
    2021-06-06
  • Spring中的Devtools源码解析

    Spring中的Devtools源码解析

    这篇文章主要介绍了Spring中的Devtools源码解析,Spring中的Devtools是一个开发工具,旨在提高开发人员的生产力和开发体验,它提供了一系列功能,包括自动重启、热部署、远程调试等,使开发人员能够更快速地进行代码修改和调试,需要的朋友可以参考下
    2023-10-10
  • jmeter接口测试教程及接口测试流程详解(全网仅有)

    jmeter接口测试教程及接口测试流程详解(全网仅有)

    Jmeter是由Apache公司开发的一个纯Java的开源项目,即可以用于做接口测试也可以用于做性能测试。本文给大家分享jmeter接口测试教程及接口测试流程,感兴趣的朋友跟随小编一起看看吧
    2021-12-12
  • Mybatis拦截器的实现介绍

    Mybatis拦截器的实现介绍

    MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能。MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。下面通过本文给大家介绍Mybatis拦截器知识,感兴趣的朋友一起看看吧
    2016-10-10
  • AJAX Servlet实现数据异步交互的方法

    AJAX Servlet实现数据异步交互的方法

    本篇文章主要介绍了AJAX Servlet实现数据异步交互的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • java多线程累加计数的实现方法

    java多线程累加计数的实现方法

    在多线程协作任务中,如何计算也是很重的,这篇文章主要介绍了java多线程累加计数的实现方法,感兴趣的朋友可以了解一下
    2021-05-05
  • springboot 整合 dubbo 的实现组聚合详情

    springboot 整合 dubbo 的实现组聚合详情

    这篇文章主要介绍了springboot整合dubbo的实现组聚合详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • java导出包含多个sheet的Excel代码示例

    java导出包含多个sheet的Excel代码示例

    这篇文章主要介绍了java导出包含多个sheet的Excel,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03

最新评论