什么是循环队列?循环队列及其实现,结合LeetCode第622题(设计循环队列)来介绍

如果对队列还有些疑问的可以线看一看我上一个博客:用Java描述数据结构之栈和队列,以及栈和队列的常用方法
当我们只有一段固定大小空间去存一个队列时像这样:
在这里插入图片描述

Front是队首,Rear是队尾,很明显这个空间已经满了,现在依次删除队首元素:
在这里插入图片描述

可以发现随着队列内元素越来越少,没有用到的空间越来越大,且总空间大小不变,所以说到最后这段空间就算是废了。

为了让这段空间可持续利用,我们其实可以这样:
在这里插入图片描述
在这里插入图片描述
就是每次头删之后将队列中所有元素向前移,这就很好的解决了问题,完美的提升了空间的利用。可是,每头删一个元素都依次将后续元素前移这个操作无疑增加了时间复杂度。
所以为了降低时间复杂度我们可以设置一段检测队列大小和数组大小关系的代码,只有满足这个条件的时候在将有效数据依次前移,这样就不必每次头删都要前移,在一定程度上降低了时间复杂度。

当然还有另外一个方案解决,就是我们根本不必前移元素,只用改变以下头尾指针(就比喻为指针了)的用法,让队列在逻辑上看起来像个环就行了,这就是我们今天的主角——循环队列:

在这里插入图片描述
这是一个空队列,现在加入元素(下面环形队列图中的Rear指向有错,Rear应该指向队尾的下一个,就是空的第一个):
在这里插入图片描述
继续加入:
在这里插入图片描述
在这里插入图片描述

现在队列满了,我们头删元素:
在这里插入图片描述
可以看到,我们头删之后队列既多出空间插入新的元素,也不必前移元素,那么怎么去实现逻辑上是个环的这个循环队列呢?其实只需更灵活的使用头尾指针就可以。

我们结合LeetCode第622题来看
LeetCode.622.
现在来讨论它的具体实现:

public class MyCircularQueue {
    //数组实现循环队列
    private int[] queueArray;
    //记录队首位置
    private int frontIndex;
    //记录队尾位置
    private int rearIndex;
    //记录队列长度
    private int size;

    //构造方法
    public MyCircularQueue(int k) {
        queueArray = new int[k];
        frontIndex = 0;
        rearIndex = 0;
        size = 0;
    }

    //插入新元素
    public boolean enQueue(int value) {
        if(size == queueArray.length){
            return false;
        }
            queueArray[rearIndex] = value;
            size++;
            rearIndex = (rearIndex + 1) % queueArray.length;
            return true;
    }

    //删除元素
    public boolean deQueue() {
        if (size == 0){
            return false;
        }
        frontIndex = (frontIndex + 1) % queueArray.length;
        size--;
        return  true;
    }

    //从队首获取元素,如果队列为空返回-1
    public int Front() {
        if(size == 0){
            return -1;
        }
        return queueArray[frontIndex];
    }
    //获取队尾元素,如果队列为空,返回-1
    public int Rear() {
        if(size == 0){
            return -1;
        }
        //rearIndex始终指向第一个空的下标,
        //所以要取队尾元素,就得取rearIndex前一个下标内的元素
        //为了防止rearIndex指向0号下标
        //做以下操作
        int index = (rearIndex - 1 + queueArray.length) % queueArray.length;
        return queueArray[index];
    }
    //判断队列是否为空
    public boolean isEmpty() {
        return size == 0;
    }
    //判断队列是否满
    public boolean isFull() {
        return size == queueArray.length;
    }
}

以上就是对循环及其实现的简单介绍,如果理解有偏差,还望看官在评论区指正,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有裂痕的石头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值