-
Notifications
You must be signed in to change notification settings - Fork 271
Expand file tree
/
Copy patharray_queue.py
More file actions
133 lines (119 loc) · 3.58 KB
/
array_queue.py
File metadata and controls
133 lines (119 loc) · 3.58 KB
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
# Python/data_structures/queue/array_queue.py
"""
Data Structure Description:
A Queue is a linear data structure that follows the First-In, First-Out (FIFO)
principle. Elements are added (enqueued) at the rear and removed (dequeued)
from the front. This implementation uses a standard Python list as the
underlying storage. While simple, dequeuing from the beginning of a Python
list can be inefficient (O(n)) as elements need to be shifted.
"""
# Time Complexity:
# - Enqueue (append): O(1) on average
# - Dequeue (pop(0)): O(n) because all subsequent elements must be shifted
# - Peek: O(1)
# - is_empty: O(1)
# - size: O(1)
# Space Complexity: O(n)
# - Where n is the number of elements stored in the queue.
class ArrayQueue:
"""Implements a queue using a Python list."""
def __init__(self):
"""Initializes an empty queue."""
self._items = []
def enqueue(self, item):
"""Adds an item to the rear of the queue.
>>> q = ArrayQueue()
>>> q.enqueue(1)
>>> q.enqueue(2)
>>> print(q._items)
[1, 2]
"""
self._items.append(item)
def dequeue(self):
"""Removes and returns the item from the front of the queue.
Raises IndexError if the queue is empty.
>>> q = ArrayQueue()
>>> q.enqueue(1)
>>> q.enqueue(2)
>>> q.dequeue()
1
>>> q.dequeue()
2
>>> q.dequeue()
Traceback (most recent call last):
...
IndexError: dequeue from empty queue
"""
if not self._items:
raise IndexError("dequeue from empty queue")
return self._items.pop(0) # Inefficient part
def peek(self):
"""Returns the item at the front of the queue without removing it.
Raises IndexError if the queue is empty.
>>> q = ArrayQueue()
>>> q.enqueue(1)
>>> q.enqueue(2)
>>> q.peek()
1
>>> q.dequeue()
1
>>> q.peek()
2
>>> q.dequeue()
2
>>> q.peek()
Traceback (most recent call last):
...
IndexError: peek from empty queue
"""
if not self._items:
raise IndexError("peek from empty queue")
return self._items[0]
def is_empty(self):
"""Returns True if the queue is empty, False otherwise.
>>> q = ArrayQueue()
>>> q.is_empty()
True
>>> q.enqueue(1)
>>> q.is_empty()
False
"""
return len(self._items) == 0
def size(self):
"""Returns the number of items in the queue.
>>> q = ArrayQueue()
>>> q.size()
0
>>> q.enqueue(1)
>>> q.enqueue(2)
>>> q.size()
2
"""
return len(self._items)
def __len__(self):
"""Allows using len(q)."""
return self.size()
def __str__(self):
"""String representation of the queue."""
return f"ArrayQueue({self._items})"
def __repr__(self):
"""Representation of the queue."""
return f"ArrayQueue({self._items})"
if __name__ == "__main__":
import doctest
doctest.testmod()
q = ArrayQueue()
print("Is queue empty?", q.is_empty())
q.enqueue("A")
q.enqueue("B")
q.enqueue("C")
print(q)
print("Size:", len(q))
print("Peek:", q.peek())
print("Dequeue:", q.dequeue())
print(q)
print("Dequeue:", q.dequeue())
print("Is queue empty?", q.is_empty())
print("Dequeue:", q.dequeue())
print("Is queue empty?", q.is_empty())
# print("Dequeue:", q.dequeue()) # This will raise IndexError