队列
- 队列是一种特殊的线性表,只能在头尾两端操作
- 队尾(rear):只能从队尾添加元素,一般叫做入队(enQueue)
- 队头(front):只能从队头移除元素,一般叫做出队(deQueue)
- 队列内部实现可以使用动态数组或双向链表实现
- 优先使用双向链表,因为队列主要往头尾操作元素
- 先进先出原则:First In First Out(FIFO)
队列的接口设计
- public lit size(); //元素数量
- public boolean isEmpty(); //是否为空
- public void enQueue(E element); //入队 说明:官方API为add()或offer()
- public void deQueue(); //出队 说明:官方API为remove()或poll()
- public E front(); //获取队列头元素 说明:官方API为peek()
队列的实现
public class Queue<E> {
private List<E> list = new LinkedList<>();
public int size() {
return list.size();
}
public boolean isEmpty() {
return list.isEmpty();
}
public void enQueue(E element) {
list.add(element);
}
public E deQueue() {
return list.remove(0);
}
public E front() {
return list.get(0);
}
}
双端队列
- 双端队列是可以在头尾两端进行添加、删除的队列
双端队列接口设计
- public lit size(); //元素数量
- public boolean isEmpty(); //是否为空
- public void enQueueFront(E element); //队头入队
- publiv void enQueueRear(E element); //队尾入队
- public void deQueueFront(); //队头出队
- public void deQueueRear() //队尾出队
- public E front(); //获取队列头元素
- public E rear(); //获取队尾元素
双端队列的实现
public class Deque<E> {
private List<E> list = new LinkedList<>();
// 元素的数量
public int size() {
return list.size();
}
// 是否为空
public boolean isEmpty() {
return list.isEmpty();
}
// 从队头出队
public E deQueueFront() {
return list.remove(0);
}
// 从队头入队
public void enQueueFront(E element) {
list.add(0, element);
}
// 从队尾入队
public void enQueueRear(E element) {
list.add(element);
}
// 从队尾出队
public E deQueueRear() {
return list.remove(list.size() - 1);
}
// 获取队列的头元素
public E front() {
return list.get(0);
}
// 获取队列的尾元素
public E rear() {
return list.get(list.size() - 1);
}
}
循环队列
- 循环队列是指用一个队头变量(front)指向数组的第一个变量
- 每一次出栈,就将front位置的元素取出并删除,然后front+1
- 每一次入栈,就根据front和当前元素数量计算出入栈元素的索引,然后将元素放到数组对应的索引位置上
循环队列的接口设计
- public lit size(); //元素数量
- public boolean isEmpty(); //是否为空
- public void enQueue(E element); //入队
- public void deQueue(); //出队
- public E front(); //获取队列头元素
循环队列的实现
public class CircleQueue<E> {
private int front;
private E[] elements;
prinvate int size;
private static final int DEFAULT_CAPACITY = 10;
public class CircleQueue() {
elements = (E []) new Object[]
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void enQueue(E element) {
ensureCapcity(size + 1);
elements[index(size)] = element;
size++;
}
public E deQueue() {
E element = elements[front];
element[front] = null;
//更新front
front = index(1); (1 + front) % elements.length
size--;
return element;
}
public E front() {
return elements[front];
}
//保证数组容量
private void ensureCapacity(int capacity) {
int oldCapacity = elements.length;
if (oldCapacity >= capacity) return;
// 新容量为旧容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[index(i)];
}
elements = newElements;
// 重置front
front = 0;
}
private int index(int index) {
return (index + front) % elements.length;
}
}