设计循环队列

设计循环队列

首先我要了解什么是循环队列,即我们开辟一段数组,用front和rear引用分别指向队头和队尾,

当我你要队头出数据后,front向后走到数组下标为1的位置,我们希望队头出数据的位置可以存放新的数据,此时我们要从数组下标为7的位置该如何回到数组 下标为0的位置呢?

这里我们提供了一个数组下标循环的小技巧:

下标最后再往后走1步: index = (index + 1) % array.length

此时让数组做到了循环,就可以形成下面这种样子

那么该如何区别数组是否存满了呢?

有三种方法:

  1. 通过添加 usedSize 属性记录 区别数组是否存满了
java 复制代码
 //循环队列1------》利用usedSize标记

    class MyCircularQueue1 {
        public int[] arr;
        int usedSize = 0;//初始有效数据为0
        public int front;
        public int rear;

        public MyCircularQueue1 (int k) {
        //开辟存放k个数据的有效空间
            int[] arr = new int[k];
        }

        //入队列

        public boolean enQueue(int value) {
        //1.如果队列满了,无法入队,返回false
            if (isFull()) {
                return false;
            }
            //2.队尾入数据
            arr[rear] = value;
            //指向队尾的指针往后走1步
            rear = (rear + 1) % arr.length;
            //数组中的有效数据+1
            usedSize++;
            return true;
        }


        //出队列

        public boolean deQueue() {
        //1.如果有效数据为0,表示队列为空,无法出队,返回false
            if (usedSize == 0) {
                return false;
            }
            //有效数据-1
            usedSize--;
            //队头往后走1步
            front = (front + 1) % arr.length;
            return true;
        }

        //取队头元素
        public int Front() {
            if (isEmpty()) {
                return -1;
            }
            return arr[front];
        }

        //取队尾元素
        public int Rear() {
            if (isEmpty()) {
                return -1;
            }
            //通过上面的if判断可知此时队中存在元素,
            //1.rear的指向若为0下标,表示已经循环一次,若直接用0-1得到的是-1下标的数据,数组越界,所以使用arr.length - 1 ,得到下标为arr.length - 1的值
            //2.若此时rear的指向不为0,则表示rear的范围在(0,k-1]范围内,直接rear-1即可
            int index = (rear == 0) ? arr.length - 1 : rear - 1;
            return arr[index];
        }

        //判断循环队列是否空了
        public boolean isEmpty() {
        //有效数据为0,表示队空
            if (usedSize == 0) {
                return true;
            }
            return false;
        }

        //判断循环队列是否满了
        public boolean isFull() {
        //有效数据==数组长度,队满
            if (usedSize == arr.length) {
                return true;
            }
            return false;
        }
    }
  1. 牺牲一个空间
java 复制代码
 class MyCircularQueue2 {
        
        public int [] arr;
        public int front=0;
        public int rear=0;
        
        public MyCircularQueue2 (int k) {
        //由于要牺牲一个空间来判断是否为满,所以多申请一个空间
           arr=new int[k+1];
        }

        public boolean enQueue(int value) {
            if(isFull()){
                return false;
            }
            arr[rear] = value;
            rear = (rear+1)%arr.length;
            return true;
        }

        public boolean deQueue() {
            if(isEmpty()){
                return false;
            }
            front = (front+1)%arr.length;
            return true;
        }

        public int Front() {
            if (isEmpty()){
                return -1;
            }
            return arr[front];
        }

        public int Rear() {
            if (isEmpty()){
                return -1;
            }
            int index = (rear == 0) ? arr.length-1 : rear-1;
            return arr[index];
        }

        public boolean isEmpty() {
        //front和rear引用指向同一个位置表示,队为空
            if(front==rear){
                return true;
            }
            return false;
        }

        //判断循环队列是否满了
        public boolean isFull() {
        //若raer跳过牺牲的一个空间后,仍然等于front 表示队满
            if((rear+1)%arr.length==front){
                return true;
            }
            return false;
        }
}
  1. 使用标记(flag)
java 复制代码
    class MyCircularQueue3 {
        public int[] arr;
        public int front;
        public int rear;
        boolean flag;//默认为false
        public MyCircularQueue3(int k) {
            arr = new int[k];
        }
        public boolean enQueue(int value) {
            if(isFull()){
                return false;
            }
            arr[rear]=value;         
            rear=(rear+1)% arr.length;
            //入队后,将flag改为true,表示队中有数据了
            flag=true;
            return true;
        }

        public boolean deQueue() {
            if(isEmpty()){
                return false;
            }
            front=(front+1)% arr.length;
            flag=false;
            return true;
        }

        public int Front() {
            if(isEmpty()){
                return -1;
            }
            return arr[front];
        }

        public int Rear() {
            if (isEmpty()) {
                return -1;
            }
            int index = (rear == 0) ? arr.length - 1 : rear - 1;
            return arr[index];
        }

        public boolean isEmpty() {
            if(front == rear && !flag) {
            return true;
        }
        return false;
        }

        public boolean isFull() {
            if (rear==front&&flag) {
                return true;
            }
            return false;
        }

    }
相关推荐
叫致寒吧2 小时前
Tomcat详解
java·tomcat
同学小张3 小时前
【端侧AI 与 C++】1. llama.cpp源码编译与本地运行
开发语言·c++·aigc·llama·agi·ai-native
踢球的打工仔4 小时前
PHP面向对象(7)
android·开发语言·php
S***26756 小时前
基于SpringBoot和Leaflet的行政区划地图掩膜效果实战
java·spring boot·后端
汤姆yu6 小时前
基于python的外卖配送及数据分析系统
开发语言·python·外卖分析
Yue丶越6 小时前
【C语言】字符函数和字符串函数
c语言·开发语言·算法
马剑威(威哥爱编程)6 小时前
鸿蒙6开发视频播放器的屏幕方向适配问题
java·音视频·harmonyos
JIngJaneIL6 小时前
社区互助|社区交易|基于springboot+vue的社区互助交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·社区互助
翔云 OCR API6 小时前
人脸识别API开发者对接代码示例
开发语言·人工智能·python·计算机视觉·ocr
V***u4537 小时前
MS SQL Server partition by 函数实战二 编排考场人员
java·服务器·开发语言