読むキューのソース
唯一のオーバーおおよそ次の質問に記入してください、ありがとうございました。
版
1.8
入門
主なインタフェースと実装
队列接口,抽象实现,优先级队列
双端队列接口,双端队列实现
- キュー
- 抽象クラスAbstractQueue <E>
- PriorityQueueクラス<E>はAbstractQueue <E>を拡張
- と
- クラスのLinkedList <E>を実装したDeque <E>
- クラスArrayDeque <E>を実装したDeque <E>
public interface Queue<E> extends Collection<E> public abstract class AbstractQueue<E> extends AbstractCollection<E> implements Queue<E> class PriorityQueue<E> extends AbstractQueue<E> public interface Deque<E> extends Queue<E> class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E> class ArrayDeque<E> extends AbstractCollection<E> implements Deque<E>
(一)LinkedListの
両端キューリンクリストの実装に基づきます。
少しご紹介。主にある両端キューを達成offer
するから、poll
取るpeek
関数ファミリを。
(B)ArrayDeque
両端キューアレイ・プロセッサ。
プロパティ
transient
ストレージ損失を低減するために、カスタム直列化順序。- インデックスセーブ頭と尾の頭と尾。
- 8の最小容量。
transient Object[] elements
transient int head
transient int tail
private static final int MIN_INITIAL_CAPACITY = 8
コンストラクタ
- デフォルト容量:16
- 必要以上:容量を指定し
MIN_INITIAL_CAPACITY =8
て、2倍の保証方式の電源の容量を確保するためにcalculateSize
head
そしてtail
デフォルト値、0(デフォルトの型部材は、ゼロ値変数に対応します)
public ArrayDeque() {
elements = new Object[16];
}
public ArrayDeque(int numElements) {
allocateElements(numElements);
}
// 测试:传入9,返回16;传入17,返回32
private static int calculateSize(int numElements) {
int initialCapacity = MIN_INITIAL_CAPACITY;
if (numElements >= initialCapacity) {
initialCapacity = numElements;
initialCapacity |= (initialCapacity >>> 1);
initialCapacity |= (initialCapacity >>> 2);
initialCapacity |= (initialCapacity >>> 4);
initialCapacity |= (initialCapacity >>> 8);
initialCapacity |= (initialCapacity >>> 16);
initialCapacity++;
if (initialCapacity < 0) // Too many elements, must back off
initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
}
return initialCapacity;
}
入ります
デフォルト:テールへ
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e;
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();
}
拡張
拡張方法:doubleCapacity()
前提条件:の全容量
:一般的方法
1.保存度:頭部、尾部、電流容量...
2.計算新しい容量:elements.length << 1
3.値を超える防ぐint
の範囲
メモリ割り当てる4
5.割り当てと移動:配列キュー以来環状回構造、使用する必要がありSystem.arrcopy
、また、0にヘッドセット、元の長さ反対尾
private void doubleCapacity() {
assert head == tail;
int p = head;
int n = elements.length;
int r = n - p; // number of elements to the right of p
int newCapacity = n << 1;
if (newCapacity < 0)
throw new IllegalStateException("Sorry, deque too big");
Object[] a = new Object[newCapacity];
System.arraycopy(elements, p, a, 0, r);
System.arraycopy(elements, 0, a, r, p);
elements = a;
head = 0;
tail = n;
}
アウト
デフォルト:ヘッダ
public E pollFirst() {
int h = head;
@SuppressWarnings("unchecked")
E result = (E) elements[h];
// Element is null if deque empty
if (result == null)
return null;
elements[h] = null; // Must null out slot
head = (h + 1) & (elements.length - 1);
return result;
}
容量計算
public int size() {
return (tail - head) & (elements.length - 1);
}
空の判決
public boolean isEmpty() {
return head == tail;
}
(C)優先度つきキュー
プライオリティキュー配列ベースの実装。
プロパティ
- デフォルト容量:11
- デフォルトコンパレータ:ヌル
private static final int DEFAULT_INITIAL_CAPACITY = 11;
transient Object[] queue
private int size = 0
private final Comparator<? super E> comparator
transient int modCount = 0
拡張
容量以下64以上、容量が50%増加し、容量は、容量を倍増、64未満です。
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);
}
入ります
テールデフォルトに、上方に調整
public boolean offer(E e) {
if (e == 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;
}
上方修正
private void siftUpComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>) x;
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (key.compareTo((E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = key;
}
アウト
デフォルトのヘッダ、尾を取るための要素をコピーしqueue[0]
、下方修正
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 siftDownComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>)x;
int half = size >>> 1; // loop while a non-leaf
while (k < half) {
int child = (k << 1) + 1; // assume left child is least
Object c = queue[child];
int right = child + 1;
if (right < size &&
((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
c = queue[child = right];
if (key.compareTo((E) c) <= 0)
break;
queue[k] = c;
k = child;
}
queue[k] = key;
}
内蔵イテレータ
左から右のように横断トップダウンスタックに従って配列を反復処理、すなわち、。