双端队列(deque)是指容许两端均可以进行入队和出队操做的队列,deque 是 “double ended queue” 的简称。那就说明元素能够从队头出队和入队,也能够从队尾出队和入队。java
双端队列的存储结构node
public class LinkedBlockingDeque<E> { //队头 Node<E> first; //队尾 Node<E> last; //元素个数 int count; static final class Node<E> { //存储元素 E item; //上一个元素 Node<E> prev; //下一个元素 Node<E> next; } }
从队头入队安全
public boolean offerFirst(Node<E> node) { //头节点临时变量 Node<E> f = first; //把当前的下一个节点指向头节点 node.next = f; //更新当前节点为头节点 first = node; //假如尾节点为空,则把当前节点设置为尾节点 if (last == null) last = node; //就把之前的头节点指向当前节点 else f.prev = node; //总数加一 ++count; return true; }
从队头出队微信
public E pollFirst() { Node<E> f = first; //头节点的下一个节点 Node<E> n = f.next; //获取头节点元素 E item = f.item; //置空 f.item = null; //孤立头节点,不指向任何节点 f.next = f; // help GC //重置头节点 first = n; //说明是最后一个节点 if (n == null) last = null; //不然把头节点的上一个节点置空 else n.prev = null; //总数减一 --count; return item; }
从队尾入队spa
public boolean offerLast(Node<E> node) { //尾节点临时变量 Node<E> l = last; if (l == null) return null; //把当前的上一个节点指向尾节点 node.prev = l; //更新当前节点为尾节点 last = node; //假如头节点为空,则把头节点置为当前节点 if (first == null) first = node; //不然把临时的尾节点的下一个节点指向当前节点 else l.next = node; //总数加一 ++count; return true; }
从队尾出队线程
public E pollLast() { Node<E> l = last; if (l == null) return null; //最后节点的上一个节点 Node<E> p = l.prev; //获取元素 E item = l.item; //置空 l.item = null; //孤立尾节点 l.prev = l; // help GC //更新尾节点 last = p; //假如是最后一个元素,置空头节点 if (p == null) first = null; //不然置空下一个节点指向 else p.next = null; //总数减一 --count; return item; }
双端队列其实和队列差很少的,只是更加灵活了,队头和队尾都可进行入队和出队操做。这里是基于链表的双端队列实现,具体详情可查看 JDK 的 LinkedBlockingDeque 的实现,它还考虑了线程安全相关的东西,这里只是简单的一个实现,了解双端队列的结构和运做方式。code
PS:
清山绿水始于尘,博学多识贵于勤。
我有酒,你有故事吗?
微信公众号:「清尘闲聊」。
欢迎一块儿谈天说地,聊代码。队列