链式队列
	由链表实现的队列;
顺序队列
	由数组实现的队列;
数组实现可变长度的队列
		思路:
	
	- 使用System.arraycopy()进行扩容、进行数据迁移
 - 记录数组有效长度、不需要记录数组的总容量
 
package com.hshuo;
/**
 * 数组实现可变长度的队列
 * @author SHshuo
 * @data 2022/2/26--11:39
 */
public class arrayToVolatileQueue {
    private int front;
    private int rear;
    private int length;
    private int[] arr;
    public arrayToVolatileQueue(int capicity){
        length = 0;
        front = 0;
        rear = 0;
        arr = new int[capicity];
    }
    private void resize(int capicity){
        int[] res = new int[capicity];
//        数据迁移时间复杂度为O(n)通过均摊,整体的add、get的时间复杂度仍为O(1)
        System.arraycopy(arr, front, res, 0, rear - front + 1);
//        重置
        rear -= front;
        front = 0;
        arr = res;
    }
    public void add(int value){
        arr[rear++] = value;
        length++;
//        超过数组长度的一半进行扩容
        if(length > 0 && length > arr.length / 2){
            resize(arr.length * 2);
        }
    }
    public int remove(){
        if(length == 0){
            throw new RuntimeException("队列空了,不能再拿了");
        }
        int ans = arr[front++];
        length--;
        if(length > 0 && length < arr.length / 4){
            resize(arr.length / 2);
        }
        return ans;
    }
    public void allData(){
        if(length == 0){
            throw new RuntimeException("队列空了");
        }
        for(int i = front; i < rear; i++){
            System.out.println("i: " + i + "arr: " + arr[i]);
        }
    }
    public static void main(String[] args) {
        arrayToVolatileQueue queue = new arrayToVolatileQueue(6);
        queue.add(1);
        queue.add(2);
        queue.add(3);
        queue.remove();
        queue.add(4);
        queue.allData();
        queue.add(5);
        queue.add(6);
        queue.add(6);
        queue.add(6);
    }
}
循环队列
数组实现容量固定的队列、可以重复利用数组
	思路:
- 数组要预留一处空间,如果容量是capicity则实际空间是capicity - 1;
 - 队列已满条件:(rear + 1)% capicity == front;
 - 队列已空条件:front == rear;
 - 指针增加:front = (front + 1)% capicity 或者 rear= (rear+ 1)% capicity ;
 - 数组的有效长度:(capicity + rear - front)% capicity;
 - 数组的下标:i % capicity;
 
package com.hshuo;
/**
 * 数组转化为固定大小的队列、重复利用数组空间,每次都要取模
 * 数组要预留一处空间,如果容量是capicity则实际空间是capicity - 1
 * @author SHshuo
 * @data 2022/2/26--9:50
 */
public class arrayToQueue {
//    数组
    private int[] arr;
    private int front;
    private int rear;
    private int capicity;
//    初始化队列
    public arrayToQueue(int capicity){
        this.capicity = capicity;
        front= 0;
        rear = 0;
        arr = new int[capicity];
    }
//    对列已满的条件
    private boolean isFull(){
        return (rear + 1) % capicity == front;
    }
//    队列已空的条件
    private boolean isEmpty(){
        return rear == front;
    }
    public void add(int value){
        if(isFull()){
            throw new RuntimeException("队列满了,不能再加了");
        }
        arr[rear] = value;
//        rear++需要取模
        rear = (rear + 1) % capicity;
    }
    public int remove(){
        if(isEmpty()){
            throw new RuntimeException("队列空了,不能再拿了");
        }
        int ans = arr[front];
        System.out.println("移除的元素是:" + ans);
//        front++需要取模
        front = (front + 1) % capicity;
        return ans;
    }
//    有效长度
    public int size(){
        if(isEmpty()){
            return 0;
        }
        return (capicity + rear - front) % capicity;
    }
//    返回所有数据
    public void allData(){
        if(isEmpty()){
            throw new RuntimeException("队列空了");
        }
        for(int i = front; i < front + size(); i++){
            System.out.println("i: " + i % capicity + "arr: " + arr[i % capicity]);
        }
    }
    public static void main(String[] args) {
        arrayToQueue queue = new arrayToQueue(6);
        queue.add(1);
        queue.add(2);
        queue.add(3);
        queue.add(4);
        queue.add(5);
        queue.remove();
        queue.add(6);
        queue.allData();
    }
}
	阻塞对列
	例如:ArrayBlockingQueue的源码
	初始化
public ArrayBlockingQueue(int capacity, boolean fair) {
        if (capacity <= 0)
            throw new IllegalArgumentException();
        this.items = new Object[capacity];
        lock = new ReentrantLock(fair);
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
    }
	(使用ReetrantLock 和 contional实现)
public void put(E e) throws InterruptedException {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == items.length)
                notFull.await();
            enqueue(e);
        } finally {
            lock.unlock();
        }
    }
public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == 0)
                notEmpty.await();
            return dequeue();
        } finally {
            lock.unlock();
        }
    }
	
京公网安备 11010502036488号