数组实现的环形队列

利用数组实现的环形队列,主要方法和思考过程都在代码里面。

package algorithm.structure;

/**
 * @Author: M˚Haonan
 * @Date: 2021/1/9 18:08
 * @Description: 数组实现的环形队列
 * 这种环形队列,队列的容量是要比数组长度少1的,因为只有留下一个空余空间,才能判断出来是满还是空
 * 如果全占,满和空的时候两个指针都是重叠的,没法判断
 */
public class ArrayQueue {

    //头指针,指向第一个元素
    private int head;

    //尾指针,指向最后一个元素之后的位置,这个非常重要
    private int tail;

    //存放元素
    private int[] arr;

    //队列的容量
    private int capacity;

    //数组的长度,比容量大1
    private int arrLen;


    public ArrayQueue(int capacity) {
        this.capacity = capacity;
        arr = new int[this.capacity + 1];
        arrLen = arr.length;
        head = 0;
        tail = 0;
    }

    //第一种满 如果tail > head 那么 tail + 1 - head == arrLen
    //第二种满 如果tail < head 那么 tail + 1 - head == 0
    //那么合二为一就是 (tail + 1 - head) % arrLen == 0;
    public boolean isFull() {
        return (tail + 1 - head) % arrLen == 0;
    }

    //当两个指针重叠的时候,队列为空
    public boolean isEmpty() {
        return head == tail;
    }

    public void add(int num) {
        if (isFull()) {
            System.out.println("队列已满,无法加入");
            return;
        }
        arr[tail] = num;
        //取余也就相当于这样 tail = tail == arrLen - 1 ? 0 : tail + 1;
        //取余的妙用,比如a % b,那么结果就是0 ~ (b - 1)循环
        tail = (tail + 1) % arrLen;
    }

    public int pop() {
        if (isEmpty()) {
            System.out.println("队列为空");
            throw new RuntimeException("队列为空");
        }
        int ele = arr[head];
        // head = head == arrLen - 1 ? 0 : head + 1;
        head = (head + 1) % arrLen;
        return ele;
    }

    public void print() {
        int currHead = head;
        int currTail = tail;
        while (currHead != currTail) {
            System.out.println(arr[currHead]);
            //currHead = currHead == arrLen - 1 ? 0 : currHead + 1;
            currHead = (currHead + 1) % arrLen;
        }
    }

    //如果tail >= head  valid = tail - head
    //如果tail < head  valid = arrLen - (head - tail)
    //                        arrLen + tail - head
    //如果合二为一,那么就是 valid = (arrLen + tail - head) % arrLen
    //取余可以保证不超过arrLen,当tail >= head时,取余可以把 + arrLen抵消掉,相当于 + 0
    //当tail < head 时,取余相当于没取余,结果是arrLen + tail - head
    public int getValidNum() {
        return (arrLen + tail - head) % arrLen;
    }



    public static void main(String[] args) {
        ArrayQueue queue = new ArrayQueue(3);
        queue.add(1);
        queue.pop();
        queue.add(2);
        queue.add(4);
        queue.pop();
        queue.add(5);
        queue.add(5);
        queue.add(5);
        System.out.println("队列有效个数为" + queue.getValidNum());
        queue.print();

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值