循环队列(Java版)

在上一篇文章的最后,我们提到了可以用循环队列来解决顺序队列只能使用一次的问题。在循环队列中,我们依然需要使用两个变量head(指向队列中的第一个元素,初始值为0)和tail(指向队列中最后一个元素的下一个位置,初始值为0)。

在顺序队列中,我们需要判断队空和队满的情况,同样在循环队列也需要判断队满和队空的情况。
循环队列
上图中这个队列大小size为8,开始队列空时head和tail都指向下标0。依次添加元素a、b,此时如上图所示head位置不变,tail向后移指向下标为2的位置。继续添加元素c、d、e、f、g, 此时tail指向了最后一个位置。

数组实现的非循环队列中,队空的情况是head == tail,循环队列中队空的情况也是head == tail。非循环队列中队满的情况是tail == size,循环队列中队满的情况是(tail + 1) % size == head

上图可以看出,当队列满时,tail指向的位置是没有存储元素的。如果我们想要最后一个位置也存储元素,那么tail需要继续向后移动一个位置,此时tail和head指向了同一个位置,与队列为空的情况是一样的条件head == tail,

所以我们约定牺牲一个存储空间来区分队空和队满的情况。

同样可以计算出队列中实际有效元素的个数为(tail + size - head) % size

下面我们使用代码来实现循环队列:

public class CircularQueue {

    private Integer[] items;

    private int size;

    private int head = 0;

    private int tail = 0;

    public CircularQueue(int size) {
        this.size = size;
        items = new Integer[size];
    }

    /**
     * 入队列
     * @param item
     * @return
     */
    public boolean enqueue(int item) {
        // 判断队列是否已满
        if((tail + 1) % size == head) {
            return false;
        }
        items[tail] = item;
        tail = (tail + 1) % size;
        return true;
    }

    /**
     * 出队列
     * @return
     */
    public Integer dequeue() {
        // 判断队列是否为空
        if(head == tail) {
            return null;
        }
        Integer item = items[head];
        items[head] = null;
        head = (head + 1) % size;

        return item;
    }

    /**
     * 打印队列中所有元素
     */
    public void list() {
        // 实际有效元素个数
        int num = (tail + size - head) % size;

        for(int i = head, len = head + num; i < len; i++) {
            System.out.println(items[i%size]);
        }
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值