-
Notifications
You must be signed in to change notification settings - Fork 0
/
Priority Queue ADT Class
201 lines (160 loc) · 7.17 KB
/
Priority Queue ADT Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
"""
-------------------------------------------------------
Priority Queue Class
-------------------------------------------------------
Author: Ryan Chisholm
__updated__ = "2023-02-01"
-------------------------------------------------------
"""
from copy import deepcopy
class Priority_Queue:
def __init__(self):
"""
-------------------------------------------------------
Initializes an empty priority queue.
Use: pq = Priority_Queue()
-------------------------------------------------------
Returns:
a new Priority_Queue object (Priority_Queue)
-------------------------------------------------------
"""
self._values = []
self._first = None
def is_empty(self):
"""
-------------------------------------------------------
Determines if the priority queue is empty.
Use: b = pq.is_empty()
-------------------------------------------------------
Returns:
True if priority queue is empty, False otherwise.
-------------------------------------------------------
"""
return len(self._values) == 0
def __len__(self):
"""
-------------------------------------------------------
Returns the length of the priority queue.
Use: n = len(pq)
-------------------------------------------------------
Returns:
the number of values in the priority queue.
-------------------------------------------------------
"""
return len(self._values)
def insert(self, value):
"""
-------------------------------------------------------
A copy of value is appended to the end of the the priority queue
Python list, and _first is updated as appropriate to the index of
value with the highest priority.
Use: pq.insert(value)
-------------------------------------------------------
Parameters:
value - a data element (?)
Returns:
None
-------------------------------------------------------
"""
self._values.append(deepcopy(value))
_values = self._values
if len(_values) == 1: #if there is only one item in queue, it is highest priority
self._first = 0 #highest priority index is the first index
if _values[-1] < _values[self._first]: #check if newest item added is higher priority
self._first = _values.index(value)
return
def peek(self):
"""
-------------------------------------------------------
Peeks at the highest priority value of the priority queue.
Use: v = pq.peek()
-------------------------------------------------------
Returns:
value - a copy of the highest priority value in the priority queue -
the value is not removed from the priority queue. (?)
-------------------------------------------------------
"""
assert len(self._values) > 0, "Cannot peek at an empty priority queue"
_values = self._values
self._set_first() #call method to determine highest priority value
value = deepcopy(self._first)
value = _values[value] #find value at index of highest priority
return value
def remove(self):
"""
-------------------------------------------------------
Removes and returns the highest priority value from the priority queue.
Use: value = pq.remove()
-------------------------------------------------------
Returns:
value - the highest priority value in the priority queue -
the value is removed from the priority queue. (?)
-------------------------------------------------------
"""
assert len(self._values) > 0, "Cannot remove from an empty priority queue"
_values = self._values
self._set_first() #call method to determine highest priority in queue
value = _values.pop(self._first) #remove value at index of highest priority
self._set_first() #call again to redefine the highest priority value after it was previously removed
return value
def _set_first(self):
"""
-------------------------------------------------------
Private helper function to set the value of _first.
_first is the index of the value with the highest
priority in the priority queue. None if queue is empty.
Use: self._set_first()
-------------------------------------------------------
Returns:
None
-------------------------------------------------------
"""
_values = self._values
if len(_values) != 0:
self._first = 0 #set default priority to be first index
for i in range(len(_values)):
if _values[i] < _values[self._first]: #compare to find highest priority
self._first = i
else:
self._first = None
def split_key(self, key):
"""
-------------------------------------------------------
Splits a priority queue into two depending on an external
priority key. The source priority queue is empty when the method
ends. The order of the values from source is preserved.
Use: target1, target2 = source.split_key(key)
-------------------------------------------------------
Parameters:
key - a data object (?)
Returns:
target1 - a priority queue that contains all values
with priority higher than key (Priority_Queue)
target2 - priority queue that contains all values with
priority lower than or equal to key (Priority_Queue)
-------------------------------------------------------
"""
_values = self._values
target1 = Priority_Queue()
target2 = Priority_Queue()
while len(_values) != 0: #until local pq is empty
value = _values.pop()
if value < key: #if removed value is higher priority than key
target1.insert(value)
else: #if removed value is equal or lesser priority than key
target2.insert(value)
return target1, target2
def __iter__(self):
"""
FOR TESTING ONLY
-------------------------------------------------------
Generates a Python iterator. Iterates through the priority queue
from front to rear. Not in priority order.
Use: for value in pq:
-------------------------------------------------------
Returns:
value - the next value in the priority queue (?)
-------------------------------------------------------
"""
for value in self._values:
yield value