什么是双端队列
上一篇博客中介绍了简单的单向队列使用单链表实现队列和栈,仅从tail处添加新节点,而双端队列可以从head、tail处加入队列,可以从head、tail处弹出队列。
那么使用单链表可以实现双端队列么?
分析一下:单链表,有head和tail节点,无论从head还是tail处添加节点是没问题的,但是弹出呢?从head弹出没问题,可以找到对应的next节点,但是如果从tail弹出节点,那么由于是单向链表,前面的节点就丢失了,找不到了,所以只能通过双向链表来实现双端队列。
使用双链表实现双端队列,需要注意的是:每次从head、tail弹出节点后,需要将老head的next指针和老tail的last指针置为null,否则JVM垃圾回收时会回收不掉。
public static class Node<V> {
public V value;
public Node<V> next;
public Node<V> last;
public Node(V value) {
value = value;
next = null;
last = null;
}
}
public static class MyDeque<V> {
private Node<V> head;
private Node<V> tail;
private int size;
public MyDeque() {
head = null;
tail = null;
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
public void pushHead(V value) {
Node node = new Node(value);
if (head == null) {
head = node;
tail = node;
} else {
head.last = node;
node.next = head;
head = node;
}
size++;
}
public void pushTail(V value) {
Node node = new Node(value);
if (head == null) {
head = node;
tail = node;
} else {
tail.next = node;
node.last = tail;
tail = node;
}
size++;
}
public V pollHead() {
V ans = null;
if (head == null) {
return ans;
}
size--;
if (head == tail) {
ans = head.value;
head = null;
tail = null;
} else {
ans = head.value;
head.next = head;
head.last = null;
}
return ans;
}
public V pollTail() {
V ans = null;
if (tail == null) {
return ans;
}
size--;
if (head == tail) {
ans = tail.value;
head = null;
tail = null;
} else {
ans = tail.value;
tail.last = tail;
tail.next = null;
}
return ans;
}
public V peekHead() {
V ans = null;
if (head != null) {
ans = head.value;
}
return ans;
}
public V peekTail() {
V ans = null;
if (tail != null) {
ans = tail.value;
}
return ans;
}
}