Title: Queues
1Queues
2The Queue ADT
- A queue is a linear list in which data can only
be inserted at one end (called the back), and
deleted from the other end (called the front). - These restrictions ensure that the data are
processed through the queue in the order in which
they are received. Another name FIFO (first-in,
first-out). - Queue resembles a waiting line.
3Basic Operations on Queues
- The basic operations supported by queues are
- queue_init() Initialize the queue.
- empty() Return true if the queue is empty.
Return false otherwise. - enqueue() insertion at the back of the queue
- dequeue() removal of the item from the front of
the queue (cannot be used on empty queue) - front() access of the item at the front of the
queue (cannot be used on empty queue)
4(No Transcript)
5Initializing a Queue
This algorithm initializes a queue to empty. An
empty queue has r f -1.
Input Parameters None Output Parameters
None queue_init() r f - 1
6Testing for an Empty Queue
This algorithm returns true if the queue is empty
or false if the queue is not empty. An empty
queue has r f -1.
Input Parameters None Output Parameters
None empty() return r - 1
7Adding an Element to a Queue
This algorithm adds the value val to a queue. The
queue is represented using an array data of size
SIZE. The algorithm assumes that the queue is not
full. The most recently added item is at index r
(rear), and the least recently added item is at
index f (front). If the queue is empty, r f
-1.
Input Parameters val Output Parameters
None enqueue(val) if (empty()) r f 0
else r r 1 if (r SIZE) r
0 datar val
8Removing an Element From a Queue
This algorithm removes the least recently added
item from a queue. The queue is represented using
an array of size SIZE. The algorithm assumes that
the queue is not empty. The most recently added
item is at index r (rear), and the least recently
added item is at index f (front). If the queue is
empty, r f -1.
Input Parameters None Output Parameters
None dequeue() // does queue contain one
item? if (r f) r f -1 else
f f 1 if (f SIZE) f 0
9Returning the Front Element in a Queue
This algorithm returns, but does not remove, the
least recently added item in a queue. The
algorithm assumes that the queue is not empty.
The queue is represented using an array data. The
least recently added item is at index f (front).
Input Parameters None Output Parameters
None front() return dataf
10Queue Interface
- public interface Queue
- public void enqueue(Object x)
- public Object getFront( ) throws Underflow
- public Object dequeue( ) throws Underflow
- public boolean isEmpty( )
- public void makeEmpty( )
11Queues
- The first-in, first-out (FIFO) queue is one of
the fundamental ADT that is similar to the
pushdown stack but uses the opposite rule to
decide which element to remove for remove. - Rather than removing the most recently inserted
element, we remove the element that has been in
the queue the longest.
12FIFO queue ADT interface
- This interface is identical to the pushdown stack
interface, except for the names of the methods.
The two ADTs differ only in the specification,
which is not reflected in the interface code. - class intQueue // ADT interface
- // implementations and private members hidden
- intQueue(int)
- int empty()
- void put(int)
- int get()
-
13FIFO queue example
This list shows the result of the sequence of
operations in the left column (top to bottom),
where a letter denotes put and an asterisk
denotes get. Each line displays the operation,
the letter returned for get operations, and the
contents of the queue in order from least
recently inserted to most recently inserted, left
to right.
14Queues
- Just as with stacs, queues can be implemented
using arrays or lists. - First, we will consider the implementation using
arrays, and then we will use linked lists. - Define a class containing an array for storing
the queue elements, and two markers one pointing
to the location of the head of the queue, and the
other to the first empty space following the
tail.
15FIFO queue example, array implementation
We implement the queue by storing the items in an
array of length 11. The indices are wrapped
back to the beginning of the array when they
reach the end of the array. In this example,
the tail index wraps back to the beginning when
the second T is inserted, and the head index
wraps when the second S is removed.
16FIFO queue array implementation
- class intQueue
- private int q
- private int N, head, tail
- intQueue(int maxN)
- q new intmaxN 1
- N maxN 1
- head N tail 0
-
- boolean empty()
- return (head N tail)
-
- void put(int item)
- qtail item
- tail tail N
-
- int get()
- head head N
- return qhead
-
The contents of the queue are all the elements in
the array between head and tail, taking into
account the wrap around back to 0 when the end of
the array is encountered. If head and tail are
equal, then we consider the queue to be empty
but if put would make them equal, then we
consider it to be full.
17Array implementation of queues
- A queue is a first in, first out (FIFO) data
structure - This is accomplished by inserting at one end (the
rear) and deleting from the other (the front)
- To insert put new element in location 4, and
set rear to 4 - To delete take element from location 0, and set
front to 1
18Array implementation of queues
- Notice how the array contents crawl to the
right as elements are inserted and deleted - This will be a problem after a while!
19Circular arrays
- We can treat the array holding the queue elements
as circular (joined at the ends)
- Elements were added to this queue in the order
11, 22, 33, 44, 55, and will be removed in the
same order - Use front (front 1) myQueue.lengthand
rear (rear 1) myQueue.length
20Full and empty queues
- If the queue were to become completely full, it
would look like this
- If we were then to remove all eight elements,
making the queue completely empty, it would look
like this
This is a problem!
21Full and empty queues solutions
- Solution 1 Keep an additional variable
- Solution 2 (Slightly more efficient) Keep a gap
between elements consider the queue full when it
has n-1 elements
22FIFO queue linked-list implementation
class intQueue private Node head, tail
private class Node int item Node next
Node(int item) this.item item next
null intQueue(int max) head null
tail null boolean empty() return
(head null) void put(int item) Node
t tail tail new Node(item) if (empty())
head tail else t.next tail int get()
int v head.item Node t head.next
head t return v
The difference between a FIFO queue and a
pushdown stack is that new items are inserted at
the end, rather than the beginning. This class
keeps a pointer tail to the last node of the list
so that the method put can add a new node by
linking that node to the node referenced by tail
and updating tail to point to the new node. The
constructor, get, and empty are identical to
their counterparts for the linked-list
pushdown-stack implementation. The node
constructor has only one parameter because new
nodes are always inserted at the end of the list
and thus have a null next field.
23Implementing a queue q using an array of size 4
f
- The method
- q.queue_init()
- initializes an emty queue.
- The rear of the queue is at indes r, and the
front of the queue is at index f . - An empty queue has r f -1.
q
r
(a)
24Implementing a queue q using an array of size 4
f
- After
- q.enqueue(61)
- We have the situation shown in (b).
- Since the first index is 0, we have
- r f 0.
q
61
r
(b)
25Implementing a queue q using an array of size 4
f
- After
- q.enqueue(7)
- We have the situation shown in (c).
- Since the first index is 0, we have
- r1, f0.
q
61
7
r
(c)
26Implementing a queue q using an array of size 4
f
- After
- q.enqueue(45)
- We have the situation shown in (d).
- Since the first index is 0, we have
- r2, f0.
q
61
7
45
r
(d)
27Implementing a queue q using an array of size 4
f
- After
- q.dequeue()
- We have the situation shown in (e).
- Since the first index is 0, we have
- r2, f1.
q
61
7
45
r
(e)
28Implementing a queue q using an array of size 4
f
- After
- q.enqueue(39)
- We have the situation shown in (f).
- Since the first index is 0, we have
- r3, f1.
q
61
7
45
39
r
(f)
29Implementing a queue q using an array of size 4
f
- After
- q.enqueue(39)
- We have the situation shown in (g).
- Since the first index is 0, we have
- r3, f1.
q
61
7
45
39
r
(g)
30Implementing a queue q using an array of size 4
f
- After
- q.enqueue(84)
- We have the situation shown in (h).
- Since the first index is 0, we have
- r0, f1.
q
84
7
45
39
r
(h)
31Implementing a queue q using an array of size 4
f
- After
- q.enqueue(22)
- We have the situation shown in (h).
- Since the first index is 0, we have
- r1, f1.
q
84
22
45
39
r
(h)
32Implementing a queue q using an array of size 4
f
- After
- q.dequeue()
- We have the situation shown in (i).
- Since the first index is 0, we have
- r-1, f-1.
- The queue is emptied.
q
84
22
45
39
r
(i)
33Linked-list queue
In this linked-list representation of a queue, we
insert new items at the end. The items in the
linked list are in order from least recently
inserted to most recently inserted, from
beginning to end. The queue is represented by
two pointers head and tail, which point to the
first and final item, respectively. To get an
item from the queue, we remove the item at the
front of the list, in the same way as we did for
stacks. To put a new item onto the queue, we set
the link field of the node referenced by tail to
point to it (center), then update tail (bottom).
34Linked-list implementation of queues
- In a queue, insertions occur at one end,
deletions at the other end - Operations at the front of a singly-linked list
(SLL) are O(1), but at the other end they are
O(n) - Because you have to find the last element each
time - BUT there is a simple way to use a singly-linked
list to implement both insertions and deletions
in O(1) time - You always need a pointer to the first thing in
the list - You can keep an additional pointer to the last
thing in the list
35SLL implementation of queues
- In an SLL you can easily find the successor of a
node, but not its predecessor - Remember, pointers (references) are one-way
- If you know where the last node in a list is,
its hard to remove that node, but its easy to
add a node after it - Hence,
- Use the first element in an SLL as the front of
the queue - Use the last element in an SLL as the rear of the
queue - Keep pointers to both the front and the rear of
the SLL
36Enqueueing a node
To enqueue (add) a node
Find the current last node
Change it to point to the new last node
Change the last pointer in the list header
37Dequeueing a node
- To dequeue (remove) a node
- Copy the pointer from the first node into the
header
38Queue implementation details
- With an array implementation
- you can have both overflow and underflow
- you should set deleted elements to null
- With a linked-list implementation
- you can have underflow
- overflow is a global out-of-memory condition
- there is no reason to set deleted elements to null
39Deques
- A deque is a double-ended queue
- Insertions and deletions can occur at either end
- Implementation is similar to that for queues
- Deques are not heavily used
- You should know what a deque is, but we wont
explore them much further
40Stack ADT
- The Stack ADT, as provided in java.util.Stack
- Stack() the constructor
- boolean empty()
- Object push(Object item)
- Object peek()
- Object pop()
- int search(Object o) Returns the 1-based
position of the object on this stack - Note You are not allowed to use java.util.Stack
(or similar classes in java.util) when your
assignment says to implement your own stack - You may use these classes in later assignments,
if you simply need a stack in the course of doing
other things
41A queue ADT
- Here is a possible queue ADT
- Queue() the constructor
- boolean empty()
- Object enqueue(Object item) add at element at
the rear - Object dequeue() remove an element from the
front - Object peek() look at the front element
- int search(Object o) Returns the 1-based
position from the front of the queue - Java does not provide a queue class
42A deque ADT
- Here is a possible deque ADT
- Deque() the constructor
- boolean empty()
- Object addAtFront(Object item)
- Object addAtRear(Object item)
- Object getFromFront()
- Object getFromRear()
- Object peekAtFront()
- Object peekAtRear()
- int search(Object o) Returns the 1-based
position from the front of the deque - Java does not provide a deque class
43The End