Download presentation
Presentation is loading. Please wait.
1
COMPSCI 107 Computer Science Fundamentals
Lecture 15 – Queues
2
Learning Outcomes At the end of the lecture, students should be able to: Describe the Queue ADT Implement the Queue ADT in Python Explain the big-O running time for a given Queue implementation Compare the efficiency of different implementations of the Queue ADT
3
Queues We all know what a queue is:
4
Queues A queue is an ordered collection of items where the addition of new items happens at one end (the rear or back of the queue) and the removal of existing items always takes place at the other end (the front of the queue). i.e. add new elements to back, remove existing elements from front First-in, first-out (FIFO) property The first item placed in the queue will be the first item removed Example: A queue of people in a bank
5
The Queue ADT The “Queue” ADT Data: Operations:
an ordered collection of elements Operations: create a new empty queue (Queue()) determine whether a queue is empty (is_empty()) add a new item to the queue (enqueue()) remove the item added first to the queue (dequeue()) look at (but don’t remove) the item added first (peek()) determine the size of a queue (how many elements) (size())
6
The Queue ADT The “Queue” ADT enqueue( item ) dequeue() is_empty()
Front of the queue Rear of the queue is_empty() peek()
7
The Queue ADT An example True 5 3 False cat 2 q = Queue()
print(q.is_empty()) q.enqueue(5) q.enqueue('cat') print(q.peek()) q.enqueue(True) print(q.size()) q.enqueue(8.4) print(q.dequeue()) True 5 3 False cat 2
8
bond like An example Let’s play a game... Starting with this word
Change only one letter per step to form a new, valid, word like Ending with this word
9
bond An example Let’s play a game... bone lone line like fond find
Starting with this word bone lone line like fond find fine line like Many possible solutions, some shorter than others
10
An example Note, although this is a “fun” example, it has real applications Consider mapping What is the shortest path between two locations? Starting with this location Transition from one “location” to another Ending with this location
11
Six degrees of Kevin Bacon
An example Note, although this is a “fun” example, it has real applications Or social network analysis: What is the shortest path between two people in a network? Six degrees of Kevin Bacon Starting with this person Transition from one “friend” to another In mathematics, academics calculate their Erdos number – Paul Erdos a Hungarian mathematician with more than 1500 publications! Ending with this person
12
good quiz An example Here is a harder one for you!
Starting with this word Change only one letter per step to form a new, valid, word 'good', 'food', 'foot', 'soot', 'slot', 'slit', 'suit', 'quit', 'quiz' quiz Ending with this word
13
An example bond Let’s go back to our word game...
We can imagine the words as forming a graph bent bead fend Two words are connected in the graph if they are different by exactly one letter bend ... band bind bold bond fond ... bone
14
An example bond Let’s go back to our word game...
We can imagine the words as forming a graph We can use a queue to find the shortest path between any two items (or “nodes”) in the graph bent bead fend bend ... band bind bold bond fond ... bone
15
An example Let’s go back to our word game...
We can imagine the words as forming a graph We can use a queue to find the shortest path between any two items (or “nodes”) in the graph q q.enqueue('bond')
16
An example Let’s go back to our word game...
We can imagine the words as forming a graph We can use a queue to find the shortest path between any two items (or “nodes”) in the graph q bond Front of queue and rear of queue q.enqueue('bond')
17
An example Let’s go back to our word game...
We can imagine the words as forming a graph We can use a queue to find the shortest path between any two items (or “nodes”) in the graph q bond Front of queue and rear of queue while (not q.is_empty()): next_word = q.dequeue() neighbours = get_neighbours(next_word) for n in neighbours: q.enqueue(n)
18
An example Let’s go back to our word game...
We can imagine the words as forming a graph We can use a queue to find the shortest path between any two items (or “nodes”) in the graph These words are all distance = 1 away from “bond” q band bold bind fond bone bend Rear of queue Front of queue while (not q.is_empty()): next_word = q.dequeue() neighbours = get_neighbours(next_word) for n in neighbours: q.enqueue(n)
19
An example Let’s go back to our word game...
We can imagine the words as forming a graph We can use a queue to find the shortest path between any two items (or “nodes”) in the graph distance = 2 distance = 1 q bead bent fend band bold bind fond bone Rear of queue Front of queue while (not q.is_empty()): next_word = q.dequeue() neighbours = get_neighbours(next_word) for n in neighbours: q.enqueue(n)
20
An example Let’s go back to our word game...
We can imagine the words as forming a graph We can use a queue to find the shortest path between any two items (or “nodes”) in the graph There is a little more detail to this: We should keep track of which nodes we have visited so that we don’t add them back to the queue We need some way of generating all of the “neighbours” We should have some way of stopping once we have found the target word This is known as a breadth-first search
21
Queues Where else have you seen queues in practice? producer consumer
Many shared resources implement a queue to handle multiple incoming requests (e.g. videos uploaded to YouTube are queued for processing) Classic “producer – consumer” model: producer consumer queue acts as a “buffer” This term is most often used in reference to routers. When packets arrive at a router, they have to be processed and transmitted. A router can only process one packet at a time. If packets arrive faster than the router can process them (such as in a burst transmission) the router puts them into the queue (also called the buffer) until it can get around to transmitting them.
22
Queues Where else have you seen queues in practice?
Twitter uses queues to handle messages: … results in devices sending us hundreds of thousands of compressed payloads every second. Each of these payloads may contain tens of events. To handle this load reliably and in a way that permits for easy linear scaling, we wanted to make the service that accepts the events be dead simple. February 17, 2015
23
Queues Where else have you seen queues in practice?
Kafka is a message queue developed originally by LinkedIn: We are pleased to open-source another piece of infrastructure software developed at LinkedIn, Kafka, a persistent, efficient, distributed message queue. Each day, a substantially large number of such events are generated. Therefore, we need a solution that’s scalable and incurs low overhead. That’s why we decided to build Kafka. In summary, Kafka has the following three design principles: (1) a very simple API for both producers and consumers; (2) low overhead in network transferring as well as on-disk storage; (3) a scaled out architecture from the beginning. January, 2011
24
Queue Implementation OK, so how can we actually implement the Queue ADT? What data structure would be appropriate?
25
Queue Implementation OK, so how can we actually implement the Queue ADT? What data structure would be appropriate? We will use a Python list Remember: the addition of new items takes place at the beginning of the list The removal of existing items takes place at the end of the list class Queue: def __init__(self): self.items = [] def is_empty(self): return self.items == [] def size(self): return len(self.items) def enqueue(self, item): self.items.insert(0,item) def dequeue(self): return self.items.pop() Enqueue (rear of the queue) Dequeue (front of the queue)
26
Exercise What is the Big-O performance of enqueue() and dequeue() using the Python list implementation? class Queue: def __init__(self): self.items = [] def is_empty(self): return self.items == [] def size(self): return len(self.items) def enqueue(self, item): self.items.insert(0,item) def dequeue(self): return self.items.pop() Enqueue (rear of the queue) Dequeue (front of the queue)
27
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item
28
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: A B C Rear of queue Front of queue
29
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: Now, let’s add “D” to the queue A B C Rear of queue Front of queue
30
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: D A B C Rear of queue Front of queue
31
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: Now, let’s add “E” to the queue D A B C Rear of queue Front of queue
32
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: Now, let’s add “E” to the queue E D A B C Rear of queue Front of queue
33
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: E D A B C Rear of queue Front of queue
34
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: Now, let’s remove the first element E D A B C Rear of queue Front of queue
35
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: E D A B Rear of queue Front of queue
36
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: OK, let’s remove the front element and add element “X” E D A B Rear of queue Front of queue
37
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: X E D A Rear of queue Front of queue
38
Circular Queue Implementation
How can we improve the performance of the “enqueue” operation? we need to avoid the “shifting” of list elements by one position to make room for the new item Just imagine we had our queue elements stored somewhere in the middle of a long list: The elements are sliding to the left! X E D A Rear of queue Front of queue
39
Circular Queue Implementation
If we have a fixed-sized list, we can imagine it (conceptually) as a circle where the end of the list (at index position size-1) wraps back around to the start of the list (at index position 0) Items currently in the queue Rear of the queue Front of the queue Conceptual view of circular queue Items can now be enqueued and dequeued in O(1)
40
Circular Queue Implementation
Use a Python list to store the items in the queue The list has an initial fixed capacity (specified via the constructor) Initially, all elements will have the special value “None” (used to represent the absence of a value in Python) We will maintain the index position of the current front of the queue and of the current rear of the queue We will also record the maximum capacity of the queue (we cannot store more elements than this size) and the number of elements in the queue
41
Circular Queue Implementation
Consider a newly constructed circular queue (capacity = 8): 1 2 3 4 5 6 7 items front back 7 MAX_QUEUE 8 count We think of this conceptually as: back front 7 6 1 5 2 4 3
42
Circular Queue Implementation
Implementation of enqueue() and dequeue(): New items are enqueued at the back index position (but only if the queue is not already full): Items are dequeued from the front index position (but only if the queue is not already empty): When either front or back advances past MAX_QUEUE - 1, it wraps around to 0 using modulus operator
43
Circular Queue Implementation
Let’s enqueue the value “12”: 1 2 3 4 5 6 7 items front back 7 MAX_QUEUE 8 We think of this conceptually as: count back front 7 6 1 5 2 4 3
44
Circular Queue Implementation
Let’s enqueue the value “12”: 1 2 3 4 5 6 7 items front 12 back MAX_QUEUE 8 We think of this conceptually as: count 1 back front 12 7 6 1 5 2 4 3
45
Circular Queue Implementation
Now let’s enqueue the value “34”: 1 2 3 4 5 6 7 items front 12 34 back 1 MAX_QUEUE 8 We think of this conceptually as: count 2 back front 12 7 34 6 1 5 2 4 3
46
Circular Queue Implementation
Now let’s enqueue the value “56”: 1 2 3 4 5 6 7 items front 12 34 56 back 2 MAX_QUEUE 8 We think of this conceptually as: count 3 back front 12 7 34 6 1 5 2 56 4 3
47
Circular Queue Implementation
Now let’s dequeue the front value: 1 2 3 4 5 6 7 items front 12 34 56 back 2 MAX_QUEUE 8 item We think of this conceptually as: count 3 back front 12 7 34 6 1 5 2 56 4 3
48
Circular Queue Implementation
Now let’s dequeue the front value: 1 2 3 4 5 6 7 items front 1 12 34 56 back 2 MAX_QUEUE 8 item We think of this conceptually as: count 2 back front 7 34 6 1 5 2 56 4 3
49
Circular Queue Implementation
The values of front and back cannot be used to distinguish between a full queue and an empty queue: back front 61 73 1 2 3 4 5 6 7 78 7 27 6 1 12 5 2 16 4 3 98 44 73 27 16 44 98 12 78 61 front back back front 1 2 3 4 5 6 7 7 6 1 5 2 4 3 front back
50
Circular Queue Implementation
The values of front and back cannot be used to distinguish between a full queue and an empty queue: 61 73 78 7 27 6 1 12 5 2 16 4 3 98 44 front back 7 6 1 5 2 4 3 front back
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.