设计循环队列

设计循环队列

在这里插入图片描述

首先我要了解什么是循环队列,即我们开辟一段数组,用front和rear引用分别指向队头和队尾,
在这里插入图片描述
当我你要队头出数据后,front向后走到数组下标为1的位置,我们希望队头出数据的位置可以存放新的数据,此时我们要从数组下标为7的位置该如何回到数组 下标为0的位置呢?
在这里插入图片描述
这里我们提供了一个数组下标循环的小技巧:

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

在这里插入图片描述
此时让数组做到了循环,就可以形成下面这种样子
在这里插入图片描述

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

有三种方法:

1. 通过添加 usedSize 属性记录 区别数组是否存满了

 //循环队列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;
        }
    }

2. 牺牲一个空间

 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;
        }
}

3. 使用标记(flag)

    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;
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值