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 |
|
---|
67 | def add(self, e:E)->bool:
|
---|
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
|
---|
79 | # So we just find insert point with dumb search.
|
---|
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 |
|
---|
87 |
|
---|
88 | def addAll(self,c:Collection[E]):
|
---|
89 | for e in c:
|
---|
90 | self.add(e)
|
---|
91 |
|
---|
92 | def __len__(self):
|
---|
93 | return len(self.__data)
|
---|
94 |
|
---|
95 | def __contains__(self, o:Any):
|
---|
96 | return o in self.__data
|
---|
97 |
|
---|
98 | def __getitem__(self, i:int)->E:
|
---|
99 | return self.__data[i]
|
---|
100 |
|
---|
101 | def __repr__(self):
|
---|
102 | return repr(self.__data)
|
---|
103 | |
---|