一、ArrayDeque數組隊列
=====================================================
【先進先出】結構
形象圖
買火車票(網上訂的不算),排隊打飯(插隊的不講究)都是這種狀態。
public class ArrayDeque<E> extends AbstractCollection<E>
implements Deque<E>, Cloneable, Serializable{
//The array in which the elements of the deque are stored
private transient E[] elements;//數組
//The index of the element at the head of the deque
private transient int head;//隊列頭
//The index at which the next element would be added to the tail of the deque
private transient int tail;//隊列尾
//The minimum capacity that we'll use for a newly created deque.
//Must be a power of 2.
private static final int MIN_INITIAL_CAPACITY = 8;//初始化數組的最小容量
}
//初始化,容量爲16public ArrayDeque() {
elements = (E[]) new Object[16];
}
數組結構
想象兩個指針,一個指向隊頭,一個指向隊尾,人隊是從隊尾入的,出隊是從隊頭出的。
1.add()
public boolean add(E e) {
addLast(e);
return true;
}
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e; //
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();//擴容,增加一倍容量double
}
private void doubleCapacity() {
int p = head;
int n = elements.length;
int r = n - p; // number of elements to the right of p
int newCapacity = n << 1;//相當於*2,擴容一倍
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 = (E[])a;
head = 0;
tail = n;
}
擴容擴容時會消除已經出隊(remove掉)的元素佔據的空間,如上圖:
入隊(a,b,c,d,e),然後出隊(a,b,c),再入隊(f直到p),add(p)後,隊列滿了,會擴容doubleCapacity(),
System.arraycopy(elements, p, a, 0, r);顯示爲上圖
elements數組的3--15(數組下標index)複製到a數組的0-12
2.remove()
public E remove() {
return removeFirst();
}
public E removeFirst() {
E x = pollFirst();
if (x == null)
throw new NoSuchElementException();
return x;
}
public E pollFirst() {
int h = head;
E result = 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;
}