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); }當容量不足的時候,會調用此方法,如果當前容量較小(小於64),則將容量增大一倍+2,如果當前容量較大,則容量增大一半
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; }當優先隊列不指定比較器的時候,插入元素,會調用siftUpComparable k表示元素將要插入的位置 這個方法的意思是,在以k為子節點的子樹插入元素x,並保持該子樹的順序。(把k看作這個子樹的葉子節點) step1:得出父元素的下標 strp2:計算出要插入元素的位置k。如果插入元素大於父元素,將父元素移動到k的位置,k移動到其父元素,並從第一步開始循環執行 step3:在k的位置插入元素
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; }刪除會調用這個方法。刪除都是將隊尾的元素替換掉刪除掉的位置 k表示元素將要插入的位置 這個方法的意思是,在k的子樹插入元素x,並保持k位置子樹的順序(x是其子樹的最小節點)。(把k看作這個子樹的根節點) 這裡要注意,像這種二叉樹結構,下標大於size<<2都是葉子節點,其他的節點都有子節點。所以注意到循環條件,如果k是葉子節點的下標,則直接替換,因為其已經沒有子樹了,那麼肯定是以其為根節點的最小元素 step1:算出k的左右節點的下標 step2:如果k大於左右節點中的最小一個,則k與最小的節點互換位置,並循環step1 step3:在k位置賦值x
查看原文:http://blog.zswlib.com/2016/10/31/jdk%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90priorityqueue/