[1230] | 1 |
|
---|
| 2 | from typing import TypeVar, Collection, Any, Generic, List
|
---|
| 3 | from tudelft.utilities.tools.comparator import Comparator, DefaultComparator
|
---|
| 4 |
|
---|
| 5 | E=TypeVar("E")
|
---|
| 6 |
|
---|
| 7 | class PriorityQueue(Generic[E]):
|
---|
| 8 | '''
|
---|
| 9 | An unbounded priority {@linkplain Queue queue} based on a priority heap.
|
---|
| 10 | The elements of the priority queue are ordered according to their
|
---|
| 11 | {@linkplain Comparable natural ordering}, or by a {@link Comparator}
|
---|
| 12 | provided at queue construction time, depending on which constructor is
|
---|
| 13 | used. A priority queue does not permit {@code null} elements.
|
---|
| 14 | A priority queue relying on natural ordering also does not permit
|
---|
| 15 | insertion of non-comparable objects (doing so may result in
|
---|
| 16 | {@code ClassCastException}).
|
---|
| 17 |
|
---|
| 18 | <p>The <em>head</em> of this queue is the <em>least</em> element
|
---|
| 19 | with respect to the specified ordering. If multiple elements are
|
---|
| 20 | tied for least value, the head is one of those elements -- ties are
|
---|
| 21 | broken arbitrarily. The queue retrieval operations {@code poll},
|
---|
| 22 | {@code remove}, {@code peek}, and {@code element} access the
|
---|
| 23 | element at the head of the queue.
|
---|
| 24 |
|
---|
| 25 | <p>A priority queue is unbounded, but has an internal
|
---|
| 26 | <i>capacity</i> governing the size of an array used to store the
|
---|
| 27 | elements on the queue. It is always at least as large as the queue
|
---|
| 28 | size. As elements are added to a priority queue, its capacity
|
---|
| 29 | grows automatically. The details of the growth policy are not
|
---|
| 30 | specified.
|
---|
| 31 |
|
---|
| 32 | <p>This class and its iterator implement all of the
|
---|
| 33 | <em>optional</em> methods of the {@link Collection} and {@link
|
---|
| 34 | Iterator} interfaces. The Iterator provided in method {@link
|
---|
| 35 | #iterator()} and the Spliterator provided in method {@link #spliterator()}
|
---|
| 36 | are <em>not</em> guaranteed to traverse the elements of
|
---|
| 37 | the priority queue in any particular order. If you need ordered
|
---|
| 38 | traversal, consider using {@code Arrays.sort(pq.toArray())}.
|
---|
| 39 |
|
---|
| 40 | <p><strong>Note that this implementation is not synchronized.</strong>
|
---|
| 41 | Multiple threads should not access a {@code PriorityQueue}
|
---|
| 42 | instance concurrently if any of the threads modifies the queue.
|
---|
| 43 | Instead, use the thread-safe {@link
|
---|
| 44 | java.util.concurrent.PriorityBlockingQueue} class.
|
---|
| 45 |
|
---|
| 46 | <p>Implementation note: this implementation provides
|
---|
| 47 | O(log(n)) time for the enqueuing and dequeuing methods
|
---|
| 48 | ({@code offer}, {@code poll}, {@code remove()} and {@code add});
|
---|
| 49 | linear time for the {@code remove(Object)} and {@code contains(Object)}
|
---|
| 50 | methods; and constant time for the retrieval methods
|
---|
| 51 | ({@code peek}, {@code element}, and {@code size}).
|
---|
| 52 |
|
---|
| 53 | <p>This class is a member of the
|
---|
| 54 | <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
|
---|
| 55 | Java Collections Framework</a>.
|
---|
| 56 | @param data a set of data of type E
|
---|
| 57 | @param comparator the comparator that will be used to order this
|
---|
| 58 | priority queue. If {@code null}, the {@linkplain Comparable
|
---|
| 59 | natural ordering} of the elements will be used.
|
---|
| 60 | @param <E> the type of elements held in this queue
|
---|
| 61 | '''
|
---|
| 62 |
|
---|
| 63 | def __init__(self, data:List[E]=[], comparator:Comparator[E]=DefaultComparator()):
|
---|
| 64 | self.__comparator:Comparator[E] = comparator
|
---|
| 65 | self.__data:List[E] = data
|
---|
| 66 |
|
---|
[1231] | 67 | def append(self, e:E)->bool:
|
---|
[1230] | 68 | '''
|
---|
| 69 | Inserts the specified element into this priority queue.
|
---|
| 70 |
|
---|
| 71 | @return {@code true}
|
---|
| 72 |
|
---|
| 73 | '''
|
---|
| 74 | if e==None:
|
---|
| 75 | raise ValueError("e is None")
|
---|
| 76 |
|
---|
| 77 |
|
---|
| 78 | # python 3.8 bisect seems unable to handke key
|
---|
[1231] | 79 | # insert is linear anyway.
|
---|
[1230] | 80 | for i in range(len(self.__data)):
|
---|
| 81 | if self.__comparator.compare(e, self.__data[i]) <0:
|
---|
| 82 | self.__data.insert(i, e)
|
---|
| 83 | return True
|
---|
| 84 | self.__data.append(e) # at last pos
|
---|
| 85 | return True
|
---|
| 86 |
|
---|
[1231] | 87 | def extend(self,c:Collection[E]):
|
---|
[1230] | 88 | for e in c:
|
---|
[1231] | 89 | self.append(e)
|
---|
| 90 |
|
---|
| 91 | def __add__(self, c:Collection[E]):
|
---|
| 92 | self.extend(c)
|
---|
| 93 |
|
---|
| 94 | def index(self, item):
|
---|
| 95 | return self.__data.index(item)
|
---|
[1230] | 96 |
|
---|
| 97 | def __len__(self):
|
---|
| 98 | return len(self.__data)
|
---|
| 99 |
|
---|
| 100 | def __contains__(self, o:Any):
|
---|
| 101 | return o in self.__data
|
---|
| 102 |
|
---|
| 103 | def __getitem__(self, i:int)->E:
|
---|
| 104 | return self.__data[i]
|
---|
| 105 |
|
---|
| 106 | def __repr__(self):
|
---|
| 107 | return repr(self.__data)
|
---|
| 108 | |
---|