队列的分类
- 顺序队列
- 链式队列
- 循环队列
- 阻塞队列
(一)顺序队列: 数组实现
代码中注释很详细的表明了逻辑
1, 入队: 空间不足–> 整理队列空余位置/扩容
2, 出队
该实现逻辑中可以给构造函数传参指定是否为自动扩容的队列
import java.util.Arrays;
/**
* 功能说明:能够自动扩容的顺序队列
* 开发人员:@author MaLi
*/
public class ArrayQueue {
private Object[] container; //队列容器
private int length; //队列容器长度
private int head; //队列首
private int tail; //队列尾
private boolean enableExpansion; //扩容
public ArrayQueue(int length) {
this(length, false);
}
public ArrayQueue(int length, boolean enableExpansion) {
this.length = length;
container = new Object[length];
head = -1;
tail = -1;
this.enableExpansion = enableExpansion;
}
/**
* 入队
* 放不下的时候, 整理空间或者扩容
* 放得下, 直接放入
*
* @param obj 入队元素
*/
public boolean enqueue(Object obj) {
// 1, 如果队列尾已经到达容器最后一个位置
if (tail == length - 1) {
//1.1 判断容器是否有空闲空间
if (tail - head < length - 1) {
//整理队列: 移动数组的前面的元素
arrangement();
//1.2判断是否允许扩容
} else if (enableExpansion) {
//没有空间, 允许扩容
expansion();
} else {
//1.3 没有空间, 不允许扩容, 放置失败
return false;
}
}
if (head == -1) {
head = 0;//第一次放入元素
}
//放入元素
container[++tail] = obj;
return true;
}
/**
* 出队
* 不断弹出head位置的元素
*
* @return head位置的元素
*/
public Object dequeue() {
Object result = null;
if (head != tail) {
//说明队列不为空
result = container[head];
container[head++] = null;
} else if (head != -1) {
// 说明head与tail指向同一个元素, 且队列不为空
result = container[head];
container[head] = null;
head = -1;
tail = -1;
}
return result;
}
/**
* 没有空间, 扩容
*/
private void expansion() {
Object[] newContainer = new Object[length * 2];
System.arraycopy(container, 0, newContainer, 0, length);
length *= 2;
container = newContainer;
}
/**
* 整理队列: 移动数组的前面的元素
*/
private void arrangement() {
System.arraycopy(container, head, container, 0, tail - head + 1);
tail -= head;
head = 0;
}
@Override
public String toString() {
return "ArrayQueue{" +
"container=" + Arrays.toString(container) +
'}';
}
}
(二)链式队列: 链表实现
/**
* 功能说明:
* head --> #1 -->...--> #n -->tail
* 开发人员:@author MaLi
*/
public class LinkedListQueue<T> {
private int length;
private Node<T> head;
private Node<T> tail;
public LinkedListQueue() {
this.head = null;
this.tail = null;
this.length = 0;
}
@Override
public String toString() {
return "LinkedListQueue{" +
"length=" + length +
", head=" + head +
", tail=" + tail +
'}';
}
public boolean enqueue(T element) {
//情况1: 如果队列为空
if (length == 0) {
tail = new Node<T>();
tail.setContent(element);
head = tail;
} else {
//情况2: 如果队列不为空
Node newTailNode = new Node(element);
tail.setNext(newTailNode);
tail = newTailNode;
}
this.length++;
return true;
}
public T dequeue() {
//情况1: 队列为空
if (length == 0) {
return null;
}
//情况2: 队列不为空
Node<T> result = head;
Node<T> newHeadNode = head.getNext();
head = newHeadNode;
result.setNext(null);
length--;
return result.getContent();
}
public static class Node<T> {
private T content;
private Node<T> next;
public Node() {
this.content = null;
this.next = null;
}
public Node(T content) {
this.content = content;
this.next = null;
}
public Node(T content, Node<T> next) {
this.content = content;
this.next = next;
}
public T getContent() {
return content;
}
public void setContent(T content) {
this.content = content;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
@Override
public String toString() {
return "Node{" +
"content=" + content +
", next=" + next +
'}';
}
}
}
测试代码
@Test
public void testClass() {
LinkedListQueue<String> queue = new LinkedListQueue();
queue.enqueue("#001");
queue.enqueue("#002");
queue.enqueue("#003");
queue.enqueue("#004");
queue.enqueue("#005");
System.out.println(queue);
}