用数组实现队列

本文探讨如何在Java中使用数组来实现循环队列,包括其基本原理和操作步骤。
摘要由CSDN通过智能技术生成

用数组实现队列


package array;

import java.util.Arrays;

public class ArrayQueue<E> {
    Object[] element;
    int size;
    int head;
    int tail;
    int capacity;// 初始容量
    int maxCapacity;// 最大容量

    public ArrayQueue(int capacity, int maxCapacity) {
        this.capacity = capacity;
        this.maxCapacity = maxCapacity;
        element = new Object[capacity];
        size = 0;
        head = 0;
        tail = 0;
    }

    public void init(int head, int tail) {
        this.head = head;
        this.tail = tail;
    }

    public E dequeue() {
        // 细节 注意不是head > tail
        if (head == tail) {
            return null;
        }
        Object poll = element[head++];
        size--;
        return (E) poll;
    }

    public boolean enqueue(E data) {
        if (!resize()) {
            return false;
        }
        element[tail++] = data;
        size++;
        return true;
    }

    /**
     * 有两种情况,一个是队列已经满了,head=0,而且tail=data.length
     * 一个是head > 0,tail = data.length
     *
     * @return
     */
    private boolean resize() {
        if (tail < element.length) {
            return true;
        }
        if (tail - head == maxCapacity) {
            return false;
        }
        if (head == 0) {
            growCapacity();
        } else {
            migrateData();
        }
        return true;
    }

    private void migrateData() {
        for (int i = head; i < tail; i++) {
            element[i - head] = element[i];
        }
        init(0, tail - head);
    }

    private void growCapacity() {
        int oldCapacity = element.length;
        int newCapacity = oldCapacity + oldCapacity << 1;
        if (newCapacity > maxCapacity) {
            newCapacity = maxCapacity;
        }
        this.element = Arrays.copyOf(this.element, newCapacity);
    }

    public static void main(String[] args) {
        ArrayQueue queue = new ArrayQueue<String>(4, 10);
        //入队列
        queue.enqueue("helius1");
        queue.enqueue("helius2");
        queue.enqueue("helius3");
        queue.enqueue("helius4");
        //此时入队列应该走扩容的逻辑
        queue.enqueue("helius5");
        queue.enqueue("helius6");
        //出队列
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        //此时入队列应该走数据搬移逻辑
        queue.enqueue("helius7");
        //出队列
        System.out.println(queue.dequeue());
        //入队列
        queue.enqueue("helius8");
        //出队列
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        //入队列
        queue.enqueue("helius9");
        queue.enqueue("helius10");
        queue.enqueue("helius11");
        queue.enqueue("helius12");
        //出队列
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());

    }


}

循环队列

public class LeetCode622 {
    int[] element;
    int capacity;
    int start;
    int end;
    int size;

    public LeetCode622(int k) {
        element = new int[k];
        this.capacity = k;
        start = 0;
        end = 0;
    }

    /**
     * [1,2,3,4,5,6] -> [X,X,3,4,5,6] -> 此时,head=2,end=6,插入7 -> [7,X,3,4,5,6] -> head=2,end=1,继续插入8,->[7,8,3,4,5,6],此时head=2,end=2,再插入9,不能插入
     * [7,8,3,4,5,6],此时head=2,end=2,再插入9,不能插入 -> dequeue -> [7,8,X,4,5,6],输出3,head=3,....->[X,X,X,X,X,X],dequeue -> 输出6,head=2,end=2 ->
     * [5,6,7,8,3,4]:tail=4,head=4
     * 插入的是,一种情况是还没满,end < element.length
     * <p>
     * 一种情况是已经满了,这个时候end要放在最前面
     *
     * @param value
     * @return
     */
    public boolean enQueue(int value) {
        // 队列满了
        if (size == capacity) {
            return false;
        }
        end = end % capacity;
        element[end] = value;
        end++;
        size++;
        return true;
    }

    private void init() {
        start = 0;
        end = 0;
    }

    public boolean deQueue() {
        // 队列中没有元素
        if (size == 0) {
            return false;
        }
        int poll = element[start];
        size--;
        start++;
        start = start % capacity;
        return true;
    }

    public int Front() {
        return isEmpty() ? -1 : element[start]; // 细节,注意是start
    }

    public int Rear() {
        return isEmpty() ? -1 : element[end - 1]; // 注意是end-1
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public boolean isFull() {
        return size == capacity;
    }

    public static void main(String[] args) {
        LeetCode622 leetCode622 = new LeetCode622(3);

        leetCode622.enQueue(3);
        int rear = leetCode622.Rear();
        int front = leetCode622.Front();
        leetCode622.deQueue();
        leetCode622.Front();
        leetCode622.deQueue();
        leetCode622.Front();
        leetCode622.enQueue(3);
        leetCode622.enQueue(3);
        leetCode622.enQueue(3);
        leetCode622.enQueue(3);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值