设计循环队列

设计循环队列

首先我要了解什么是循环队列,即我们开辟一段数组,用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;
        }

    }
相关推荐
2402_857589361 分钟前
SpringBoot框架:作业管理技术新解
java·spring boot·后端
HBryce245 分钟前
缓存-基础概念
java·缓存
一只爱打拳的程序猿19 分钟前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
杨荧21 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck23 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
白子寰27 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
XuanRanDev36 分钟前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
代码猪猪傻瓜coding38 分钟前
力扣1 两数之和
数据结构·算法·leetcode
王俊山IT39 分钟前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。41 分钟前
c++多线程
java·开发语言