Java数据结构-数组实现循环队列

数组实现循环队列


前言

程序实现是Java语言。本文仅个人理解,仅供参考。若有不正之处,欢迎评论指出!


一、队列

队列是个什么呢?队列是一种数据的存储结构,具有先入先出,后入后出的特点。
举几个例子(虽然可能有点····):第一个就是我们人的吃与拉!这就是一个典型的队列,今天吃的与明天吃的相比较,今天的消化之后的**肯定比明天先排出!!!
还有就是银行医院等的排号办理业务,排在前面的先办理,办理完毕走人,然后才轮到后面的人办理.

图大概就如下(取元素先取队头方向的,添加元素从队尾方向加入):

在这里插入图片描述

二、循环队列

1.概念:

当出队一个元素头指针向后移动一位,入队一个元素尾指针就同样向后移动一位。这里的后可以理解成:顺时针方向。
如图:成环状的队列,就是循环队列,一般约定队尾指向的位置为空,不存数据,至于那些前辈大佬们为什么这么约定,下面再说说我的理解。出队的元素总是靠近对头方向的,入队元素总是从靠近队尾方向入的。
在这里插入图片描述

2.具有的一些特点,以及对这些特点的看法理解

初始化:front = rear = 0;

队列空:根据初始化的状态就是队列空的状态,所以就得出:front = rear的时候就是队列空的时候。

队列满:(rear + 1)% maxsize = front这相当于就是判断队列是否为空的公式吧,为什么呢?maxsize代表的是数组的长度,rear与front按照数组的下标来看,我们的约定是rear指向的地方不存值,那么根据约定来,“存满”就是rear加上一个1 的后等于front,这个没毛病。

那么问题来了,为啥留空呢?还要加1,浪费空间又麻烦?不是的,根据队列空的状态来看,假如没有这个约定,那么队列满的状态(先抛开maxsize不管)也是front = rear!是不是冲突了?所以还是有作用的。

那么对那个maxsize取余的目的是啥?因为它是一个环状的,定长的,所以就是为了避免加1后越出数组的下标边界,所以才对数组长度进行取余,避免了这个错误,也不改变结果。

判断队列中现存的有效的元素个数:(rear - front +maxsize) % maxSize,有些地方写成了:(rear +maxsize - front) % maxsize,但是为了方便讲解我的理解(为啥这样写)就看我的那个吧。

首先,我们单从maxsize来看,把rear-front看成一个正数(其实结果按理本来也就应该是一个正数,因为数组没有负数下标),我们对于:一个正数加上某个正数以后,再对和 – 取余 --加上的这个数,其结果与不加是一样的,然而当这个数是负数的时候,其结果恰好是为正数时的相反数,理解起来没任何毛病对吧?其实随便自己举两个例子就知道了。再来一句!个数不可能为负数!这样就懂了吧?看似“多此一举”其实不然,是为了避免出现负数个数的情况,

最后!上代码!(示例):

import java.util.Scanner;

/**
 * @program: 环形队列
 * @description: 环形队列实验
 * @author: Mr.XiaoShi
 * @create: 2020-12-24 21:01
 **/

public class CircularQueue {
    public static void main(String[] args) {
        CircularQueue cs = new CircularQueue(8);
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("0、插入\t1、取出\t2、查看队头\t3、遍历队列\t4、有效个数\t5、退出");
            /*手动捕获自己抛出的异常*/
            try {
                switch (sc.next()){
                    case "0":System.out.print("请输入一个整数:");break;
                    case "1":System.out.println("对头元素:"+cs.dequeue()+"已取出!");break;
                    case "2":System.out.println("对头元素为:"+cs.getQueueHead());break;
                    case "3":System.out.println("当前队列元素:\n");cs.queueShow();break;
                    case "4":System.out.println("队列有效元素个数为:"+cs.getEffectiveNumber());break;
                    case "5":System.out.println("退出程序!");return;
                }
            }catch (Exception e){
                System.out.println(e.getMessage());    //输出异常,提示!
            }
        }
    }
    private int maxSize;   //最大容量
    private int rear;      //尾指针
    private int front;     //头指针
    private int [] queue;  //队列
    /*构造器:根据传入长度创建数组*/
    public CircularQueue(int maxSize) {
        this.maxSize = maxSize;
        queue = new int[maxSize];
    }
    /*队空*/
    public boolean queueEmpty(){
        return rear == front;
    }
    /*队满*/
    public boolean queueFull(){
        return (rear +1 ) % maxSize == front;
    }
    /*查看有效元素个数*/
    public int getEffectiveNumber(){
        return (rear - front +maxSize) % maxSize;
    }

    /**
    *@Description: 查看对头元素,但不取出
    *@Param:
    *@return: front指向的(int)元素
    *@Author: your name
    *@date: 2020/12/24 0024
    **/
    public int getQueueHead(){
        if (queueEmpty()){
            throw new RuntimeException("队列空");   //手动抛出异常,既能结束方法,又能提示出错误信息
        }
        else
            return queue[front];
    }
    /**
    *@Description: 完成入队操作
    *@Param: element:元素的意思,插入的元素
    *@return: void
    *@Author: your name
    *@date: 2020/12/24 0024
    **/
    public void enqueue(int element){
        if (queueFull()){
            throw new RuntimeException("队列满,插入失败!");  //抛出异常
        }
        queue[rear++] = element;
        rear %= maxSize;
    }
    /**
    *@Description: 完成出队操作
    *@Param:
    *@return: int类型的当前对头指向元素
    *@Author: your name
    *@date: 2020/12/24 0024
    **/
    public int dequeue(){
        if (queueEmpty()){
            throw new RuntimeException("队列空");
        }
        int tmp = queue[front++];
        front %= maxSize;
        return tmp;
    }
    /**
    *@Description: 遍历队列元素,但不取出
    *@Author: your name
    *@date: 2020/12/24 0024
    **/
    public void queueShow(){
        if (queueEmpty()){
            throw new RuntimeException("队列空");
        }
        for (int i = front; i < front + getEffectiveNumber(); i++) {
            System.out.println("queue["+i % maxSize+"] = "+queue[i % maxSize]);
        }
    }
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值