/** * 创建一个指定容量大小的 PriorityQueue,它根据元素的自然顺序对其元素进行排序。 * * @param initialCapacity the initial capacity for this priority queue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ publicPriorityQueue(int initialCapacity){ this(initialCapacity, null); }
/** * 创建一个默认初始容量为 11 的 PriorityQueue,它根据指定的比较器对其元素进行排序。 * * @param comparator the comparator that will be used to order this * priority queue. If {@code null}, the {@linkplain Comparable * natural ordering} of the elements will be used. * @since 1.8 */ publicPriorityQueue(Comparator<? super E> comparator){ this(DEFAULT_INITIAL_CAPACITY, comparator); }
/** * * @param initialCapacity 优先级队列的初始容量 * @param comparator 将用于排序此优先级队列的比较器。如果为 null,将使用元素的 {@linkplain Comparable 自然排序}。 * @throws IllegalArgumentException if {@code initialCapacity} is less than 1 */ publicPriorityQueue(int initialCapacity, Comparator<? super E> comparator){ // Note: This restriction of at least one is not actually needed, // but continues for 1.5 compatibility if (initialCapacity < 1) thrownew IllegalArgumentException();
// 创建数组容器 this.queue = new Object[initialCapacity];
// 设置元素比较器,可以为空 this.comparator = comparator; }
添加元素
add()
1 2 3 4 5 6 7 8 9 10 11 12 13
/** * 将指定元素插入此优先级队列。 * * @return {@code true} (as specified by {@link Collection#add}) * @throws ClassCastException if the specified element cannot be * compared with elements currently in this priority queue * according to the priority queue's ordering * @throws NullPointerException if the specified element is null */ publicbooleanadd(E e){ // 直接调用 offer 方法 return offer(e); }
/** * @param k the position to fill 计划要插入的位置 * @param x the item to insert 要插入的元素 */ privatevoidsiftUp(int k, E x){ // 根据是否有比较器,使用不同的方法 if (comparator != null) // 使用比较器排序 siftUpUsingComparator(k, x); else // 按照元素自然顺序 siftUpComparable(k, x); }
/** * 出队 * * @return */ @SuppressWarnings("unchecked") public E poll(){ // 队列为空 if (size == 0) returnnull;
// 队列元素个数减 1 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; }
队列为空,直接返回 null 即可;
队列非空,队列元素个数减 1;
将队列首元素弹出(此时堆顶元素就没了,堆的特性可能被破坏);
取出队列末元素,将其作为参考的新的堆顶元素,为后续堆调整做准备;
如果队列在弹出元素后就为空了,那么就不需要调整堆了,否则需要做自上而下的堆调整;
注意:在出队的逻辑中,没有涉及到队列缩容的逻辑。
siftDown()
1 2 3 4 5 6 7 8 9 10 11 12 13
/** * 在位置 k 处插入项 x,即自上而下的堆调整。 * * @param k the position to fill 要填补的位置 * @param x the item to insert 要插入的元素 */ privatevoidsiftDown(int k, E x){ // 根据是否有比较器,选择不同的方法进行元素的比较,进而调整堆 if (comparator != null) siftDownUsingComparator(k, x); else siftDownComparable(k, x); }
/** * * 从队列中移除指定的元素,如果元素不存在,则返回 false * * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ publicbooleanremove(Object o){ // 获取指定元素在队列中的下标 int i = indexOf(o);