雙端隊列(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:
清山綠水始於塵,博學多識貴於勤。
我有酒,你有故事嗎?
微信公衆號:「清塵閒聊」。
歡迎一塊兒談天說地,聊代碼。隊列