1   /*
2    * %W% %E%
3    *
4    * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
5    * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6    */
7   
8   package java.util;
9   
10  /**
11   * An unbounded priority {@linkplain Queue queue} based on a priority heap.
12   * The elements of the priority queue are ordered according to their
13   * {@linkplain Comparable natural ordering}, or by a {@link Comparator}
14   * provided at queue construction time, depending on which constructor is
15   * used.  A priority queue does not permit {@code null} elements.
16   * A priority queue relying on natural ordering also does not permit
17   * insertion of non-comparable objects (doing so may result in
18   * {@code ClassCastException}).
19   *
20   * <p>The <em>head</em> of this queue is the <em>least</em> element
21   * with respect to the specified ordering.  If multiple elements are
22   * tied for least value, the head is one of those elements -- ties are
23   * broken arbitrarily.  The queue retrieval operations {@code poll},
24   * {@code remove}, {@code peek}, and {@code element} access the
25   * element at the head of the queue.
26   *
27   * <p>A priority queue is unbounded, but has an internal
28   * <i>capacity</i> governing the size of an array used to store the
29   * elements on the queue.  It is always at least as large as the queue
30   * size.  As elements are added to a priority queue, its capacity
31   * grows automatically.  The details of the growth policy are not
32   * specified.
33   *
34   * <p>This class and its iterator implement all of the
35   * <em>optional</em> methods of the {@link Collection} and {@link
36   * Iterator} interfaces.  The Iterator provided in method {@link
37   * #iterator()} is <em>not</em> guaranteed to traverse the elements of
38   * the priority queue in any particular order. If you need ordered
39   * traversal, consider using {@code Arrays.sort(pq.toArray())}.
40   *
41   * <p> <strong>Note that this implementation is not synchronized.</strong>
42   * Multiple threads should not access a {@code PriorityQueue}
43   * instance concurrently if any of the threads modifies the queue.
44   * Instead, use the thread-safe {@link
45   * java.util.concurrent.PriorityBlockingQueue} class.
46   *
47   * <p>Implementation note: this implementation provides
48   * O(log(n)) time for the enqueing and dequeing methods
49   * ({@code offer}, {@code poll}, {@code remove()} and {@code add});
50   * linear time for the {@code remove(Object)} and {@code contains(Object)}
51   * methods; and constant time for the retrieval methods
52   * ({@code peek}, {@code element}, and {@code size}).
53   *
54   * <p>This class is a member of the
55   * <a href="{@docRoot}/../technotes/guides/collections/index.html">
56   * Java Collections Framework</a>.
57   *
58   * @since 1.5
59   * @version %I%, %G%
60   * @author Josh Bloch, Doug Lea
61   * @param <E> the type of elements held in this collection
62   */
63  public class PriorityQueue<E> extends AbstractQueue<E>
64      implements java.io.Serializable {
65  
66      private static final long serialVersionUID = -7720805057305804111L;
67  
68      private static final int DEFAULT_INITIAL_CAPACITY = 11;
69  
70      /**
71       * Priority queue represented as a balanced binary heap: the two
72       * children of queue[n] are queue[2*n+1] and queue[2*(n+1)].  The
73       * priority queue is ordered by comparator, or by the elements'
74       * natural ordering, if comparator is null: For each node n in the
75       * heap and each descendant d of n, n <= d.  The element with the
76       * lowest value is in queue[0], assuming the queue is nonempty.
77       */
78      private transient Object[] queue;
79  
80      /**
81       * The number of elements in the priority queue.
82       */
83      private int size = 0;
84  
85      /**
86       * The comparator, or null if priority queue uses elements'
87       * natural ordering.
88       */
89      private final Comparator<? super E> comparator;
90  
91      /**
92       * The number of times this priority queue has been
93       * <i>structurally modified</i>.  See AbstractList for gory details.
94       */
95      private transient int modCount = 0;
96  
97      /**
98       * Creates a {@code PriorityQueue} with the default initial
99       * capacity (11) that orders its elements according to their
100      * {@linkplain Comparable natural ordering}.
101      */
102     public PriorityQueue() {
103         this(DEFAULT_INITIAL_CAPACITY, null);
104     }
105 
106     /**
107      * Creates a {@code PriorityQueue} with the specified initial
108      * capacity that orders its elements according to their
109      * {@linkplain Comparable natural ordering}.
110      *
111      * @param initialCapacity the initial capacity for this priority queue
112      * @throws IllegalArgumentException if {@code initialCapacity} is less
113      *         than 1
114      */
115     public PriorityQueue(int initialCapacity) {
116         this(initialCapacity, null);
117     }
118 
119     /**
120      * Creates a {@code PriorityQueue} with the specified initial capacity
121      * that orders its elements according to the specified comparator.
122      *
123      * @param  initialCapacity the initial capacity for this priority queue
124      * @param  comparator the comparator that will be used to order this
125      *         priority queue.  If {@code null}, the {@linkplain Comparable
126      *         natural ordering} of the elements will be used.
127      * @throws IllegalArgumentException if {@code initialCapacity} is
128      *         less than 1
129      */
130     public PriorityQueue(int initialCapacity,
131                          Comparator<? super E> comparator) {
132         // Note: This restriction of at least one is not actually needed,
133         // but continues for 1.5 compatibility
134         if (initialCapacity < 1)
135             throw new IllegalArgumentException();
136         this.queue = new Object[initialCapacity];
137         this.comparator = comparator;
138     }
139 
140     /**
141      * Creates a {@code PriorityQueue} containing the elements in the
142      * specified collection.  If the specified collection is an instance of
143      * a {@link SortedSet} or is another {@code PriorityQueue}, this
144      * priority queue will be ordered according to the same ordering.
145      * Otherwise, this priority queue will be ordered according to the
146      * {@linkplain Comparable natural ordering} of its elements.
147      *
148      * @param  c the collection whose elements are to be placed
149      *         into this priority queue
150      * @throws ClassCastException if elements of the specified collection
151      *         cannot be compared to one another according to the priority
152      *         queue's ordering
153      * @throws NullPointerException if the specified collection or any
154      *         of its elements are null
155      */
156     public PriorityQueue(Collection<? extends E> c) {
157         initFromCollection(c);
158         if (c instanceof SortedSet)
159             comparator = (Comparator<? super E>)
160                 ((SortedSet<? extends E>)c).comparator();
161         else if (c instanceof PriorityQueue)
162             comparator = (Comparator<? super E>)
163                 ((PriorityQueue<? extends E>)c).comparator();
164         else {
165             comparator = null;
166             heapify();
167         }
168     }
169 
170     /**
171      * Creates a {@code PriorityQueue} containing the elements in the
172      * specified priority queue.  This priority queue will be
173      * ordered according to the same ordering as the given priority
174      * queue.
175      *
176      * @param  c the priority queue whose elements are to be placed
177      *         into this priority queue
178      * @throws ClassCastException if elements of {@code c} cannot be
179      *         compared to one another according to {@code c}'s
180      *         ordering
181      * @throws NullPointerException if the specified priority queue or any
182      *         of its elements are null
183      */
184     public PriorityQueue(PriorityQueue<? extends E> c) {
185         comparator = (Comparator<? super E>)c.comparator();
186         initFromCollection(c);
187     }
188 
189     /**
190      * Creates a {@code PriorityQueue} containing the elements in the
191      * specified sorted set.   This priority queue will be ordered
192      * according to the same ordering as the given sorted set.
193      *
194      * @param  c the sorted set whose elements are to be placed
195      *         into this priority queue
196      * @throws ClassCastException if elements of the specified sorted
197      *         set cannot be compared to one another according to the
198      *         sorted set's ordering
199      * @throws NullPointerException if the specified sorted set or any
200      *         of its elements are null
201      */
202     public PriorityQueue(SortedSet<? extends E> c) {
203         comparator = (Comparator<? super E>)c.comparator();
204         initFromCollection(c);
205     }
206 
207     /**
208      * Initializes queue array with elements from the given Collection.
209      *
210      * @param c the collection
211      */
212     private void initFromCollection(Collection<? extends E> c) {
213         Object[] a = c.toArray();
214         // If c.toArray incorrectly doesn't return Object[], copy it.
215         if (a.getClass() != Object[].class)
216             a = Arrays.copyOf(a, a.length, Object[].class);
217         queue = a;
218         size = a.length;
219     }
220 
221     /**
222      * Increases the capacity of the array.
223      *
224      * @param minCapacity the desired minimum capacity
225      */
226     private void grow(int minCapacity) {
227         if (minCapacity < 0) // overflow
228             throw new OutOfMemoryError();
229     int oldCapacity = queue.length;
230         // Double size if small; else grow by 50%
231         int newCapacity = ((oldCapacity < 64)?
232                            ((oldCapacity + 1) * 2):
233                            ((oldCapacity / 2) * 3));
234         if (newCapacity < 0) // overflow
235             newCapacity = Integer.MAX_VALUE;
236         if (newCapacity < minCapacity)
237             newCapacity = minCapacity;
238         queue = Arrays.copyOf(queue, newCapacity);
239     }
240 
241     /**
242      * Inserts the specified element into this priority queue.
243      *
244      * @return {@code true} (as specified by {@link Collection#add})
245      * @throws ClassCastException if the specified element cannot be
246      *         compared with elements currently in this priority queue
247      *         according to the priority queue's ordering
248      * @throws NullPointerException if the specified element is null
249      */
250     public boolean add(E e) {
251         return offer(e);
252     }
253 
254     /**
255      * Inserts the specified element into this priority queue.
256      *
257      * @return {@code true} (as specified by {@link Queue#offer})
258      * @throws ClassCastException if the specified element cannot be
259      *         compared with elements currently in this priority queue
260      *         according to the priority queue's ordering
261      * @throws NullPointerException if the specified element is null
262      */
263     public boolean offer(E e) {
264         if (e == null)
265             throw new NullPointerException();
266         modCount++;
267         int i = size;
268         if (i >= queue.length)
269             grow(i + 1);
270         size = i + 1;
271         if (i == 0)
272             queue[0] = e;
273         else
274             siftUp(i, e);
275         return true;
276     }
277 
278     public E peek() {
279         if (size == 0)
280             return null;
281         return (E) queue[0];
282     }
283 
284     private int indexOf(Object o) {
285     if (o != null) {
286             for (int i = 0; i < size; i++)
287                 if (o.equals(queue[i]))
288                     return i;
289         }
290         return -1;
291     }
292 
293     /**
294      * Removes a single instance of the specified element from this queue,
295      * if it is present.  More formally, removes an element {@code e} such
296      * that {@code o.equals(e)}, if this queue contains one or more such
297      * elements.  Returns {@code true} if and only if this queue contained
298      * the specified element (or equivalently, if this queue changed as a
299      * result of the call).
300      *
301      * @param o element to be removed from this queue, if present
302      * @return {@code true} if this queue changed as a result of the call
303      */
304     public boolean remove(Object o) {
305     int i = indexOf(o);
306     if (i == -1)
307         return false;
308     else {
309         removeAt(i);
310         return true;
311     }
312     }
313 
314     /**
315      * Version of remove using reference equality, not equals.
316      * Needed by iterator.remove.
317      *
318      * @param o element to be removed from this queue, if present
319      * @return {@code true} if removed
320      */
321     boolean removeEq(Object o) {
322     for (int i = 0; i < size; i++) {
323         if (o == queue[i]) {
324                 removeAt(i);
325                 return true;
326             }
327         }
328         return false;
329     }
330 
331     /**
332      * Returns {@code true} if this queue contains the specified element.
333      * More formally, returns {@code true} if and only if this queue contains
334      * at least one element {@code e} such that {@code o.equals(e)}.
335      *
336      * @param o object to be checked for containment in this queue
337      * @return {@code true} if this queue contains the specified element
338      */
339     public boolean contains(Object o) {
340     return indexOf(o) != -1;
341     }
342 
343     /**
344      * Returns an array containing all of the elements in this queue.
345      * The elements are in no particular order.
346      *
347      * <p>The returned array will be "safe" in that no references to it are
348      * maintained by this queue.  (In other words, this method must allocate
349      * a new array).  The caller is thus free to modify the returned array.
350      *
351      * <p>This method acts as bridge between array-based and collection-based
352      * APIs.
353      *
354      * @return an array containing all of the elements in this queue
355      */
356     public Object[] toArray() {
357         return Arrays.copyOf(queue, size);
358     }
359 
360     /**
361      * Returns an array containing all of the elements in this queue; the
362      * runtime type of the returned array is that of the specified array.
363      * The returned array elements are in no particular order.
364      * If the queue fits in the specified array, it is returned therein.
365      * Otherwise, a new array is allocated with the runtime type of the
366      * specified array and the size of this queue.
367      *
368      * <p>If the queue fits in the specified array with room to spare
369      * (i.e., the array has more elements than the queue), the element in
370      * the array immediately following the end of the collection is set to
371      * {@code null}.
372      *
373      * <p>Like the {@link #toArray()} method, this method acts as bridge between
374      * array-based and collection-based APIs.  Further, this method allows
375      * precise control over the runtime type of the output array, and may,
376      * under certain circumstances, be used to save allocation costs.
377      *
378      * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
379      * The following code can be used to dump the queue into a newly
380      * allocated array of <tt>String</tt>:
381      *
382      * <pre>
383      *     String[] y = x.toArray(new String[0]);</pre>
384      *
385      * Note that <tt>toArray(new Object[0])</tt> is identical in function to
386      * <tt>toArray()</tt>.
387      *
388      * @param a the array into which the elements of the queue are to
389      *          be stored, if it is big enough; otherwise, a new array of the
390      *          same runtime type is allocated for this purpose.
391      * @return an array containing all of the elements in this queue
392      * @throws ArrayStoreException if the runtime type of the specified array
393      *         is not a supertype of the runtime type of every element in
394      *         this queue
395      * @throws NullPointerException if the specified array is null
396      */
397     public <T> T[] toArray(T[] a) {
398         if (a.length < size)
399             // Make a new array of a's runtime type, but my contents:
400             return (T[]) Arrays.copyOf(queue, size, a.getClass());
401     System.arraycopy(queue, 0, a, 0, size);
402         if (a.length > size)
403             a[size] = null;
404         return a;
405     }
406 
407     /**
408      * Returns an iterator over the elements in this queue. The iterator
409      * does not return the elements in any particular order.
410      *
411      * @return an iterator over the elements in this queue
412      */
413     public Iterator<E> iterator() {
414         return new Itr();
415     }
416 
417     private final class Itr implements Iterator<E> {
418         /**
419          * Index (into queue array) of element to be returned by
420          * subsequent call to next.
421          */
422         private int cursor = 0;
423 
424         /**
425          * Index of element returned by most recent call to next,
426          * unless that element came from the forgetMeNot list.
427          * Set to -1 if element is deleted by a call to remove.
428          */
429         private int lastRet = -1;
430 
431         /**
432          * A queue of elements that were moved from the unvisited portion of
433          * the heap into the visited portion as a result of "unlucky" element
434          * removals during the iteration.  (Unlucky element removals are those
435          * that require a siftup instead of a siftdown.)  We must visit all of
436          * the elements in this list to complete the iteration.  We do this
437          * after we've completed the "normal" iteration.
438          *
439          * We expect that most iterations, even those involving removals,
440          * will not need to store elements in this field.
441          */
442         private ArrayDeque<E> forgetMeNot = null;
443 
444         /**
445          * Element returned by the most recent call to next iff that
446          * element was drawn from the forgetMeNot list.
447          */
448         private E lastRetElt = null;
449 
450         /**
451          * The modCount value that the iterator believes that the backing
452          * Queue should have.  If this expectation is violated, the iterator
453          * has detected concurrent modification.
454          */
455         private int expectedModCount = modCount;
456 
457         public boolean hasNext() {
458             return cursor < size ||
459                 (forgetMeNot != null && !forgetMeNot.isEmpty());
460         }
461 
462         public E next() {
463             if (expectedModCount != modCount)
464                 throw new ConcurrentModificationException();
465             if (cursor < size)
466                 return (E) queue[lastRet = cursor++];
467             if (forgetMeNot != null) {
468                 lastRet = -1;
469                 lastRetElt = forgetMeNot.poll();
470                 if (lastRetElt != null)
471                     return lastRetElt;
472             }
473             throw new NoSuchElementException();
474         }
475 
476         public void remove() {
477             if (expectedModCount != modCount)
478                 throw new ConcurrentModificationException();
479             if (lastRet != -1) {
480                 E moved = PriorityQueue.this.removeAt(lastRet);
481                 lastRet = -1;
482                 if (moved == null)
483                     cursor--;
484                 else {
485                     if (forgetMeNot == null)
486                         forgetMeNot = new ArrayDeque<E>();
487                     forgetMeNot.add(moved);
488                 }
489             } else if (lastRetElt != null) {
490                 PriorityQueue.this.removeEq(lastRetElt);
491                 lastRetElt = null;
492             } else {
493                 throw new IllegalStateException();
494         }
495             expectedModCount = modCount;
496         }
497     }
498 
499     public int size() {
500         return size;
501     }
502 
503     /**
504      * Removes all of the elements from this priority queue.
505      * The queue will be empty after this call returns.
506      */
507     public void clear() {
508         modCount++;
509         for (int i = 0; i < size; i++)
510             queue[i] = null;
511         size = 0;
512     }
513 
514     public E poll() {
515         if (size == 0)
516             return null;
517         int s = --size;
518         modCount++;
519         E result = (E) queue[0];
520         E x = (E) queue[s];
521         queue[s] = null;
522         if (s != 0)
523             siftDown(0, x);
524         return result;
525     }
526 
527     /**
528      * Removes the ith element from queue.
529      *
530      * Normally this method leaves the elements at up to i-1,
531      * inclusive, untouched.  Under these circumstances, it returns
532      * null.  Occasionally, in order to maintain the heap invariant,
533      * it must swap a later element of the list with one earlier than
534      * i.  Under these circumstances, this method returns the element
535      * that was previously at the end of the list and is now at some
536      * position before i. This fact is used by iterator.remove so as to
537      * avoid missing traversing elements.
538      */
539     private E removeAt(int i) {
540         assert i >= 0 && i < size;
541         modCount++;
542         int s = --size;
543         if (s == i) // removed last element
544             queue[i] = null;
545         else {
546             E moved = (E) queue[s];
547             queue[s] = null;
548             siftDown(i, moved);
549             if (queue[i] == moved) {
550                 siftUp(i, moved);
551                 if (queue[i] != moved)
552                     return moved;
553             }
554         }
555         return null;
556     }
557 
558     /**
559      * Inserts item x at position k, maintaining heap invariant by
560      * promoting x up the tree until it is greater than or equal to
561      * its parent, or is the root.
562      *
563      * To simplify and speed up coercions and comparisons. the
564      * Comparable and Comparator versions are separated into different
565      * methods that are otherwise identical. (Similarly for siftDown.)
566      *
567      * @param k the position to fill
568      * @param x the item to insert
569      */
570     private void siftUp(int k, E x) {
571         if (comparator != null)
572             siftUpUsingComparator(k, x);
573         else
574             siftUpComparable(k, x);
575     }
576 
577     private void siftUpComparable(int k, E x) {
578         Comparable<? super E> key = (Comparable<? super E>) x;
579         while (k > 0) {
580             int parent = (k - 1) >>> 1;
581             Object e = queue[parent];
582             if (key.compareTo((E) e) >= 0)
583                 break;
584             queue[k] = e;
585             k = parent;
586         }
587         queue[k] = key;
588     }
589 
590     private void siftUpUsingComparator(int k, E x) {
591         while (k > 0) {
592             int parent = (k - 1) >>> 1;
593             Object e = queue[parent];
594             if (comparator.compare(x, (E) e) >= 0)
595                 break;
596             queue[k] = e;
597             k = parent;
598         }
599         queue[k] = x;
600     }
601 
602     /**
603      * Inserts item x at position k, maintaining heap invariant by
604      * demoting x down the tree repeatedly until it is less than or
605      * equal to its children or is a leaf.
606      *
607      * @param k the position to fill
608      * @param x the item to insert
609      */
610     private void siftDown(int k, E x) {
611         if (comparator != null)
612             siftDownUsingComparator(k, x);
613         else
614             siftDownComparable(k, x);
615     }
616 
617     private void siftDownComparable(int k, E x) {
618         Comparable<? super E> key = (Comparable<? super E>)x;
619         int half = size >>> 1;        // loop while a non-leaf
620         while (k < half) {
621             int child = (k << 1) + 1; // assume left child is least
622             Object c = queue[child];
623             int right = child + 1;
624             if (right < size &&
625                 ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
626                 c = queue[child = right];
627             if (key.compareTo((E) c) <= 0)
628                 break;
629             queue[k] = c;
630             k = child;
631         }
632         queue[k] = key;
633     }
634 
635     private void siftDownUsingComparator(int k, E x) {
636         int half = size >>> 1;
637         while (k < half) {
638             int child = (k << 1) + 1;
639             Object c = queue[child];
640             int right = child + 1;
641             if (right < size &&
642                 comparator.compare((E) c, (E) queue[right]) > 0)
643                 c = queue[child = right];
644             if (comparator.compare(x, (E) c) <= 0)
645                 break;
646             queue[k] = c;
647             k = child;
648         }
649         queue[k] = x;
650     }
651 
652     /**
653      * Establishes the heap invariant (described above) in the entire tree,
654      * assuming nothing about the order of the elements prior to the call.
655      */
656     private void heapify() {
657         for (int i = (size >>> 1) - 1; i >= 0; i--)
658             siftDown(i, (E) queue[i]);
659     }
660 
661     /**
662      * Returns the comparator used to order the elements in this
663      * queue, or {@code null} if this queue is sorted according to
664      * the {@linkplain Comparable natural ordering} of its elements.
665      *
666      * @return the comparator used to order this queue, or
667      *         {@code null} if this queue is sorted according to the
668      *         natural ordering of its elements
669      */
670     public Comparator<? super E> comparator() {
671         return comparator;
672     }
673 
674     /**
675      * Saves the state of the instance to a stream (that
676      * is, serializes it).
677      *
678      * @serialData The length of the array backing the instance is
679      *             emitted (int), followed by all of its elements
680      *             (each an {@code Object}) in the proper order.
681      * @param s the stream
682      */
683     private void writeObject(java.io.ObjectOutputStream s)
684         throws java.io.IOException{
685         // Write out element count, and any hidden stuff
686         s.defaultWriteObject();
687 
688         // Write out array length, for compatibility with 1.5 version
689         s.writeInt(Math.max(2, size + 1));
690 
691         // Write out all elements in the "proper order".
692         for (int i = 0; i < size; i++)
693             s.writeObject(queue[i]);
694     }
695 
696     /**
697      * Reconstitutes the {@code PriorityQueue} instance from a stream
698      * (that is, deserializes it).
699      *
700      * @param s the stream
701      */
702     private void readObject(java.io.ObjectInputStream s)
703         throws java.io.IOException, ClassNotFoundException {
704         // Read in size, and any hidden stuff
705         s.defaultReadObject();
706 
707         // Read in (and discard) array length
708         s.readInt();
709 
710     queue = new Object[size];
711 
712         // Read in all elements.
713         for (int i = 0; i < size; i++)
714             queue[i] = s.readObject();
715 
716     // Elements are guaranteed to be in "proper order", but the
717     // spec has never explained what that might be.
718     heapify();
719     }
720 }
721