设计循环队列

设计循环队列

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

    }
相关推荐
Kisorge17 分钟前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
路在脚下@1 小时前
spring boot的配置文件属性注入到类的静态属性
java·spring boot·sql
森屿Serien1 小时前
Spring Boot常用注解
java·spring boot·后端
轻口味1 小时前
命名空间与模块化概述
开发语言·前端·javascript
苹果醋32 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
晓纪同学2 小时前
QT-简单视觉框架代码
开发语言·qt
威桑2 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
Hello.Reader2 小时前
深入解析 Apache APISIX
java·apache
飞飞-躺着更舒服2 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生2 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb