source: utilitiespy/tudelft/utilities/tools/queue.py@ 1292

Last change on this file since 1292 was 1248, checked in by wouter, 5 weeks ago

#386 fixed bug in python PriorityQueue

File size: 4.5 KB
Line 
1
2from typing import TypeVar, Collection, Any, Generic, List
3from tudelft.utilities.tools.comparator import Comparator, DefaultComparator
4
5E=TypeVar("E")
6
7class 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]=[]
66 self.extend(data)
67
68 def append(self, e:E)->bool:
69 '''
70 Inserts the specified element into this priority queue.
71
72 @return {@code true}
73
74 '''
75 if e==None:
76 raise ValueError("e is None")
77
78
79 # python 3.8 bisect seems unable to handke key
80 # insert is linear anyway.
81 for i in range(len(self.__data)):
82 if self.__comparator.compare(e, self.__data[i]) <0:
83 self.__data.insert(i, e)
84 return True
85 self.__data.append(e) # at last pos
86 return True
87
88 def extend(self,c:Collection[E]):
89 for e in c:
90 self.append(e)
91
92 def __add__(self, c:Collection[E]):
93 self.extend(c)
94
95 def index(self, item):
96 return self.__data.index(item)
97
98 def __len__(self):
99 return len(self.__data)
100
101 def __contains__(self, o:Any):
102 return o in self.__data
103
104 def __getitem__(self, i:int)->E:
105 return self.__data[i]
106
107 def __repr__(self):
108 return repr(self.__data)
109
110 '''
111 Remove the item at the given position in the list, and return it. If
112 It raises an IndexError if the list is empty or the index is outside the list range.
113 '''
114 def pop(self, n:int) -> E:
115 return self.__data.pop(n)
116
Note: See TracBrowser for help on using the repository browser.