-
Notifications
You must be signed in to change notification settings - Fork 0
/
Circular Queue ADT Class
233 lines (185 loc) · 7.8 KB
/
Circular 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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
"""
-------------------------------------------------------
[program description]
-------------------------------------------------------
Author: Ryan Chisholm
__updated__ = "2023-02-10"
-------------------------------------------------------
"""
from copy import deepcopy
class Queue:
"""
-------------------------------------------------------
Constants
-------------------------------------------------------
"""
# a default maximum size when one is not provided
DEFAULT_CAPACITY = 10
def __init__(self, capacity=DEFAULT_CAPACITY):
"""
-------------------------------------------------------
Initializes an empty queue. Data is stored in a fixed-size list.
Use: target = Queue(capacity)
Use: target = Queue() # uses default capacity
-------------------------------------------------------
Parameters:
capacity - maximum size of the queue (int > 0)
Returns:
a new Queue object (Queue)
-------------------------------------------------------
"""
assert capacity > 0, "Queue size must be > 0"
self._capacity = capacity
self._values = [None] * self._capacity
self._front = None # queue has no data
self._rear = 0 # first available index for insertion
self._count = 0 # number of data items
def is_empty(self):
"""
-------------------------------------------------------
Determines if the queue is empty.
Use: empty = source.is_empty()
-------------------------------------------------------
Returns:
True if the queue is empty, False otherwise.
-------------------------------------------------------
"""
return self._count == 0
def is_full(self):
"""
-------------------------------------------------------
Determines if the queue is full.
Use: full = source.is_full()
-------------------------------------------------------
Returns:
True if the queue is full, False otherwise.
-------------------------------------------------------
"""
return self._count == self._capacity
def __len__(self):
"""
-------------------------------------------------------
Returns the length of the queue.
Use: n = len(source)
-------------------------------------------------------
Returns:
the number of values in the queue.
-------------------------------------------------------
"""
return self._count
def __eq__(self, target):
"""
----------------
Determines whether two Queues are equal.
Values in self and target are compared and if all values are equal
and in the same order, returns True, otherwise returns False.
Use: equals = source == target
---------------
Parameters:
target - a queue (Queue)
Returns:
equals - True if source contains the same values
as target in the same order, otherwise False. (boolean)
---------------
"""
_values = self._values
equals = False
i = deepcopy(self._front)
j = 0
t = [] #temp list for easier comparison
for values in target: #add values in target to list
t.append(values)
if t[j] in _values and self._count == len(t): #make sure they have same number of values, can't be equal if values are missing
while t[j] != _values[i]:
j += 1 #find value where both are equal, start comparison from there
while t[j] == _values[i] and i < (self._count - 1): #run until they are not equal, or reach the end of local queue
j += 1
i += 1
if j >= len(t) and i < self._count: #circular queue, avoid going out of range
j = j - len(t)
if i == (self._count - 1): #ending i value is equal to end of queue, meaning the loop went all the way through without finding any unequal values
equals = True
return equals
def insert(self, value):
"""
-------------------------------------------------------
Adds a copy of value to the rear of the queue.
Use: source.insert( value )
-------------------------------------------------------
Parameters:
value - a data element (?)
Returns:
None
-------------------------------------------------------
"""
assert self._rear is not None, "Cannot add to a full queue"
_values = self._values
_rear = self._rear
i = 0
if _rear >= len(_values) and self._count != self._capacity: #checks if value is out of range of queue, assumes it is linear, not circular
index = _rear - len(_values)
_values[index] = deepcopy(value)
else:
_values[_rear] = deepcopy(value) #add copy of value at rear of queue
self._rear += 1 #rear index increases
self._count += 1 #each time insert is called, count is increased
if self._count == 1: #if there is onlt one value in queue
while _values[i] is None and i < len(_values): #find front
i += 1
self._front = i
return
def remove(self):
"""
-------------------------------------------------------
Removes and returns value from the queue.
Use: v = source.remove()
-------------------------------------------------------
Returns:
value - the value at the front of the queue - the value is
removed from the queue (?)
-------------------------------------------------------
"""
assert self._front is not None, "Cannot remove from an empty queue"
_values = self._values
_front = self._front
value = _values[_front] #value to be removed, assigned to value, so it can be returned
_values[_front] = None #removal
self._front += 1 #move front to next value
self._count -= 1 #decrease count
return value
def peek(self):
"""
-------------------------------------------------------
Peeks at the front of queue.
Use: v = source.peek()
-------------------------------------------------------
Returns:
value - a copy of the value at the front of the queue -
the value is not removed from the queue (?)
-------------------------------------------------------
"""
assert self._count > 0, "Cannot peek at an empty queue"
_values = self._values
_front = self._front
value = deepcopy(_values[_front])
return value
def __iter__(self):
"""
USE FOR TESTING ONLY
-------------------------------------------------------
Generates a Python iterator. Iterates through the queue
from front to rear.
Use: for v in cq:
-------------------------------------------------------
Returns:
value - the next value in the queue (?)
-------------------------------------------------------
"""
if self._front is not None:
# queue is not empty
j = self._front
i = 0
while i < self._count:
yield self._values[j]
i += 1
j = (j + 1) % self._capacity