链式队列
由链表实现的队列;
顺序队列
由数组实现的队列;
数组实现可变长度的队列
思路:
- 使用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号