概述
队列也是一种受限制的线性表,大家都知道它的特性是先进先出
,根据内部数据结构的不同,可以分为顺序队列
和链式队列
,而对于数组实现的顺序队列,可以通过循环队列
的方式提高其效率,而循环队列也是应用最多的一种队列(因为循环队列可以配合CAS实现并发队列)
队列的一个很重要的应用是对于有限资源的排队使用,比如线程池、连接池等的实现
ArrayQueue数组队列
/**
* @Classname ArrayQueue
* @Description 基于数组实现的顺序队列
* @Date 2019/12/15 18:15
* @Created by SunCheng
*/
public class ArrayQueue<E> {
// ArrayList是自动扩容的,但是这里我们只是需要它已经实现好的元素操作后的位移
// 所以这里我们模拟的是一个有固定容量的队列
private ArrayList<E> data;
private int capacity;
public ArrayQueue(int capacity) {
data = new ArrayList<>(capacity);
this.capacity = capacity;
}
public int getCapacity() {
return capacity;
}
public int getSize(){
return data.size();
}
public boolean isEmpty(){
return data.isEmpty();
}
public void enqueue(E e) {
if (data.size() >= capacity) {
}
data.add(e);
}
public E dequeue() {
if (data.size() <= 0) {
throw new IllegalArgumentException("队列为空");
}
return data.remove(0);
}
public E getFront(){
if (data.size() <= 0) {
throw new IllegalArgumentException("队列为空");
}
return data.get(0);
}
}
LoopQueue循环队列
循环队列需要注意的有这么几点
- 判空条件
- 队列满的条件
- 数组中会浪费一个空间
代码中已略去一些常规性代码,比如getSize()
之类的
/**
* @Classname LoopQueue
* @Description 循环队列
* @Date 2019/12/15 18:19
* @Created by SunCheng
*/
public class LoopQueue<E> {
private E[] data;
private int front,tail;
private int size;
public LoopQueue(int capacity) {
data = (E[]) new Object[capacity+1];
front = 0;
tail = 0;
size = 0;
}
public void enqueue(E e) {
// 注意循环队列满的情况
if ((tail + 1) % data.length == front) {
resize(getCapacity() << 1);
}
data[tail] = e;
tail = (tail+1)%data.length;
size++;
}
public E dequeue() {
if (isEmpty()) {
throw new IllegalArgumentException("队列为空");
}
E ret = data[front];
data[front] = null;
front = (front+1)%data.length;
size--;
if (size == getCapacity() /4 && getCapacity()/2 != 0) {
resize(getCapacity() / 2);
}
return ret;
}
private void resize(int newCapacity) {
E[] newData = (E[]) new Object[newCapacity+1];
for (int i = 0; i < size; i++) {
newData[i] = data[(front + i) % data.length];
}
data = newData;
front = 0;
tail = size;
}
}
LinkedListQueue链式队列
链式队列实现起来就非常简单了
/**
* @Classname LinkedListQueue
* @Description 链式队列
* @Date 2019/12/15 18:16
* @Created by SunCheng
*/
public class LinkedListQueue<E> {
private LinkedList<E> data;
public LinkedListQueue() {
data = new LinkedList<>();
}
public void enqueue(E e) {
data.addLast(e);
}
public E dequeue() {
return data.removeFirst();
}
}