PriorityQueue
單端隊列,隊列中的元素有優先級的順序java
// 存儲隊列元素的數組 transient Object[] queue; // 隊列中實際元素的個數 private int size = 0; // 比較器,用於定義隊列中元素的優先級 private final Comparator<? super E> comparator;
從成員變量的定義能夠看出,底層數據存儲依然是數組,然而同javadoc中解釋,實際的存儲結構倒是二叉樹(大頂堆,小頂堆);數組
至於隊列中成員的優先級使用comparator
或者成員變量自己的比較來肯定數據結構
下面經過添加和刪除元素來肯定數據結構code
public E poll() { if (size == 0) return null; int s = --size; modCount++; // 第一個元素爲隊列頭 E result = (E) queue[0]; E x = (E) queue[s]; queue[s] = null; if (s != 0) // 隊列非空,對剩下的元素進行重排 siftDown(0, x); return result; } private void siftDown(int k, E x) { if (comparator != null) siftDownUsingComparator(k, x); else siftDownComparable(k, x); } private void siftDownUsingComparator(int k, E x) { int half = size >>> 1; while (k < half) { int child = (k << 1) + 1; Object c = queue[child]; int right = child + 1; if (right < size && comparator.compare((E) c, (E) queue[right]) > 0) c = queue[child = right]; if (comparator.compare(x, (E) c) <= 0) break; queue[k] = c; k = child; } queue[k] = x; }
shifDownUsingComparator
實現的就是維持小頂堆二叉樹的邏輯,後面以添加爲例,給一個圖解接口
肯定存儲結構爲小頂堆以後,再看添加元素隊列
public boolean offer(E e) { if (e == null) // 非null throw new NullPointerException(); modCount++; int i = size; if (i >= queue.length) // 動態擴容 grow(i + 1); size = i + 1; if (i == 0) queue[0] = e; else siftUp(i, e); return true; } // 擴容邏輯,擴容爲新size的兩倍,或者新增原來容量的一半 private void grow(int minCapacity) { int oldCapacity = queue.length; // Double size if small; else grow by 50% int newCapacity = oldCapacity + ((oldCapacity < 64) ? (oldCapacity + 2) : (oldCapacity >> 1)); // overflow-conscious code if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); queue = Arrays.copyOf(queue, newCapacity); } // 二叉樹重排 private void siftUp(int k, E x) { if (comparator != null) siftUpUsingComparator(k, x); else siftUpComparable(k, x); } private void siftUpUsingComparator(int k, E x) { while (k > 0) { int parent = (k - 1) >>> 1; Object e = queue[parent]; if (comparator.compare(x, (E) e) >= 0) break; queue[k] = e; k = parent; } queue[k] = x; }
PriorityQueue
存儲結構爲二叉樹,小頂堆