chapter objectives
DESCRIPTION
Chapter Objectives. L earn how to represent a waiting line (queue) Become proficient using the methods in the Queue U nderstand how to implement the Queue interface using a single-linked list, a circular array double-linked list - PowerPoint PPT PresentationTRANSCRIPT
Chapter Objectives Learn how to represent a waiting line (queue) Become proficient using the methods in the Queue Understand how to implement the Queue interface using
a single-linked list, a circular array double-linked list
Analyze the pros and cons for different Queue implementations
Become familiar with the Deque interface its methods Simulate the operation of a physical system that has one
or more waiting lines
CS340 1
Queue• The queue, like the stack, is a widely used data structure• A queue differs from a stack in one important way
• A stack is LIFO list – Last-In, First-Out• while a queue is FIFO list, First-In, First-Out
CS340 2
Queue Abstract Data Type
CS340 3
Queue Abstract Data Type Line of customers waiting for serviceSimilar to a stack
We do not access the “middle” objects Pointer in the head as in stack Additional pointer on tail
CS340 4
More Queues Operating systems use queues to
keep track of tasks ensure that the tasks are carried out in the order they were
generated Print queue
CS340 5
Specification for a Queue Interface
The Queue interface implements the Collection interface
CS340 6
Class LinkedList Implements the Queue Interface
LinkedList class implements the Queue interfaceQueue<String> names = new LinkedList<String>();
CS340 7
Implementing the Queue Interface
CS340 8
Using a Double-Linked List to Implement the Queue Interface
Insertion and removal from either end of a double-linked list is ???
Problem: Other LinkedList methods in addition to the ones required and permitted by the Queue interface
Solution: Create a new class with a LinkedList component
CS340 9
Using a Single-Linked List to Implement a Queue
• Insertions are at the rear of a queue and removals are from the front
• We need a reference to the last list node so that insertions can be performed at O(1)
• The number of elements in the queue is changed by methods insert and remove
CS340 10
Implementing a Queue Using an Array Single- or double-linked list is time efficient BUT Space inefficiencies
Storage space increased due to references stored in the nodes Array Implementation
Insertion at rear of array is ?? Removal from the front is ?? Removal from rear of array is ?? Insertion at the front is ??
CS340 11
[ 0 ]
An array of integers to implement a queue of integers
4 8 6
We don't care what's inthis part of the array.
[ 1 ] [ 2 ] [ 3 ] [ 4 ] size3
first0
last2
Implementing a Queue Using an Array
CS340 12
dequeue()
[ 0 ] . . .
8 6
[ 1 ] [ 2 ] [ 3 ] [ 4 ]size3
first0
last2
4
[ 0 ]
8 6
[ 1 ] [ 2 ] [ 3 ] [ 4 ] size2
first0
last1
Implementing a Queue Using an Array
CS340 13
dequeue()
[ 0 ]
8 6
[ 1 ] [ 2 ] [ 3 ] [ 4 ]size3
first0
last2
4
[ 0 ]
6
[ 1 ] [ 2 ] [ 3 ] [ 4 ] size2
first0
last1
8
Implementing a Queue Using an Array
CS340 14
dequeue() takes O(n)!
dequeue()
size3
first0
last2
[ 0 ]
4[ 1 ]
8
[ 2 ]
6
[ 3 ]
[ 4 ]
Solution: Cyclic ArrayCS340 15
size2
first1
last2
[ 0 ]
[ 1 ]
8
[ 2 ]
6
[ 3 ]
[ 4 ]
enqueue(2) dequeue() dequeue() enqueue(12) enqueue(5)
Cyclic Array (cont.)CS340 16
size3
first3
last0
[ 0 ]
[ 1 ]
[ 2 ] [ 3 ]
[ 4 ]
2
12
5
Cyclic Array (cont.)
CS340 17
Implementing a Queue Using a Circular Array (cont.)
18
Implementing a Queue Using a Circular Array (cont.)
CS340 19
Implementing a Queue Using a Circular Array (cont.)
CS340 20
size = 0front = 0
rear = 4
public ArrayQueue(int initCapacity) { capacity = initCapacity; theData = (E[])new Object[capacity]; front = 0; rear = capacity – 1; size = 0;}
ArrayQueue q = new ArrayQueue(5);
capacity = 5
Implementing a Queue Using a Circular Array (cont.)
CS340 21
size = 0front = 0
rear = 4
public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true;}
q.offer('*');
capacity = 5
1rear = 0
*
Implementing a Queue Using a Circular Array (cont.)
CS340 22
size = 1front = 0
rear = 1
public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true;}
q.offer('+');
capacity = 5
2rear = 0
*
+
Implementing a Queue Using a Circular Array (cont.)
CS340 23
size = 2front = 0
rear = 1
public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true;}
q.offer('/');
capacity = 5
3*
+
rear = 2 /
Implementing a Queue Using a Circular Array (cont.)
CS340 24
size = 3front = 0
rear = 3public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true;}
q.offer('-');
capacity = 5
4*
+
rear = 2 /
-
Implementing a Queue Using a Circular Array (cont.)
CS340 25
size = 4front = 0
rear = 4
public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true;}
q.offer('A');
capacity = 5
5*
+
rear = 3
/
A
-
CS340 26
size = 5front = 0
public E poll() { if (size == 0) { return null } E result = theData[front]; front = (front + 1) % capacity; size--; return result;}
next = q.poll();
capacity = 5
4*
+
/
-
result = '*'
front = 1
Arear = 4
Implementing a Queue Using a Circular Array (cont.)
CS340 27
size = 4
front = 1
public E poll() { if (size == 0) { return null } E result = theData[front]; front = (front + 1) % capacity; size--; return result;}
next = q.poll();
capacity = 5
3*
+
/
-
result = '+'
front = 2
Arear = 4
Implementing a Queue Using a Circular Array (cont.)
CS340 28
size = 3
public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true;}
q.offer('B');
capacity = 5
4*
+
/
-
front = 2
Arear = 4
rear = 0 B
Implementing a Queue Using a Circular Array (cont.)
CS340 29
size = 4
public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true;}
q.offer('C');
capacity = 5
5B
+
/
-
front = 2
A
rear = 0
rear = 1 C
Implementing a Queue Using a Circular Array (cont.)
CS340 30
size = 5
public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true;}
q.offer('D');
capacity = 5B
+
/
-
front = 2
A
rear = 1 C
Implementing a Queue Using a Circular Array (cont.)
CS340 31
size = 5
private void reallocate() { int newCapacity = 2 * capacity; E[] newData = (E[])new Object[newCapacity]; int j = front; for (int i = 0; i < size; i++) { newData[i] = theData[j]; j = (j + 1) % capacity; } front = 0; rear = size – 1; capacity = newCapacity; theData = newData;}
q.offer('D');
capacity = 5B
+
/
-
front = 2
A
rear = 1 C
B
+/
-
front = 2
A
rear = 1 C
newCapacity = 10
theData
Implementing a Queue Using a Circular Array (cont.)
CS340 32
Implementing a Queue Using a Circular Array (cont.)
size = 5
private void reallocate() { int newCapacity = 2 * capacity; E[] newData = (E[])new Object[newCapacity]; int j = front; for (int i = 0; i < size; i++) { newData[i] = theData[j]; j = (j + 1) % capacity; } front = 0; rear = size – 1; capacity = newCapacity; theData = newData;}
q.offer('D');
capacity = 5
B
+/
-
front = 2
A
rear = 1 C
newCapacity = 10
j = 2
i = 0
newData
theData
CS340 33
Implementing a Queue Using a Circular Array (cont.)
size = 5
private void reallocate() { int newCapacity = 2 * capacity; E[] newData = (E[])new Object[newCapacity]; int j = front; for (int i = 0; i < size; i++) { newData[i] = theData[j]; j = (j + 1) % capacity; } front = 0; rear = size – 1; capacity = newCapacity; theData = newData;}
q.offer('D');
capacity = 5
B
+/
-
front = 2
A
rear = 1 C
newCapacity = 10
j = 2
i = 0
/
/
j = 3
i = 1
newData
theData
CS340 34
Implementing a Queue Using a Circular Array (cont.)
size = 5
private void reallocate() { int newCapacity = 2 * capacity; E[] newData = (E[])new Object[newCapacity]; int j = front; for (int i = 0; i < size; i++) { newData[i] = theData[j]; j = (j + 1) % capacity; } front = 0; rear = size – 1; capacity = newCapacity; theData = newData;}
q.offer('D');
capacity = 5
B
+/
-
front = 2
A
rear = 1 C
newCapacity = 10
j = 3
i = 1
-
-
j = 4
i = 2
/
newData
theData
CS340 35
Implementing a Queue Using a Circular Array (cont.)
size = 5
private void reallocate() { int newCapacity = 2 * capacity; E[] newData = (E[])new Object[newCapacity]; int j = front; for (int i = 0; i < size; i++) { newData[i] = theData[j]; j = (j + 1) % capacity; } front = 0; rear = size – 1; capacity = newCapacity; theData = newData;}
q.offer('D');
capacity = 5
B
+/
-
front = 2
A
rear = 1 C
newCapacity = 10
j = 0
i = 2
A
A
j = 4i = 3
/
-
newData
theData
CS340 36
Implementing a Queue Using a Circular Array (cont.)
size = 5
private void reallocate() { int newCapacity = 2 * capacity; E[] newData = (E[])new Object[newCapacity]; int j = front; for (int i = 0; i < size; i++) { newData[i] = theData[j]; j = (j + 1) % capacity; } front = 0; rear = size – 1; capacity = newCapacity; theData = newData;}
q.offer('D');
capacity = 5
B
+/
-
front = 2
A
rear = 1 C
newCapacity = 10
j = 1
i = 3
B
B
j = 0
i = 4
/
-
A
newData
theData
CS340 37
Implementing a Queue Using a Circular Array (cont.)
size = 5
private void reallocate() { int newCapacity = 2 * capacity; E[] newData = (E[])new Object[newCapacity]; int j = front; for (int i = 0; i < size; i++) { newData[i] = theData[j]; j = (j + 1) % capacity; } front = 0; rear = size – 1; capacity = newCapacity; theData = newData;}
q.offer('D');
capacity = 5
B
+/
-
front = 2
A
rear = 1 C
newCapacity = 10
j = 2
i = 4
C
C
j = 1
i = 5
/
-
A
B
newData
theData
newData
CS340 38
Implementing a Queue Using a Circular Array (cont.)
size = 5
private void reallocate() { int newCapacity = 2 * capacity; E[] newData = (E[])new Object[newCapacity]; int j = front; for (int i = 0; i < size; i++) { newData[i] = theData[j]; j = (j + 1) % capacity; } front = 0; rear = size – 1; capacity = newCapacity; theData = newData;}
q.offer('D');
capacity = 5front = 2
rear = 1
newCapacity = 10
C
i = 5
/
-
A
B
B
+/
-
A
C
j = 2
C
theData
front = 0
rear = 4
10
CS340 39
Implementing a Queue Using a Circular Array (cont.)
size = 5
q.offer('D');
capacity = 5
C
/
-
A
B
newData
front = 0
rear = 4
10
public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true;}
6
rear = 5 D
Implementing Class ArrayQueue<E>.Iter (cont.)
private class Iter implements Iterator<E> { private int index; private int count = 0;
public Iter() { index = front; }
@Override public boolean hasNext() { return count < size; } ....
CS340 40
• Just as for class ListQueue<E>, we must implement the missing:
• Queue methods • class Iter
Implementing Class ArrayQueue<E>.Iter (cont.)
private class Iter implements Iterator<E> { private int index; private int count = 0;
public Iter() { index = front; }
@Override public boolean hasNext() { return count < size; } ....
CS340 41
• Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queue interface
index stores the subscript of the next element to be accessed
Implementing Class ArrayQueue<E>.Iter (cont.)
private class Iter implements Iterator<E> { private int index; private int count = 0;
public Iter() { index = front; }
@Override public boolean hasNext() { return count < size; } ....
CS340 42
• Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queue interface
The constructor initializes index to front when a new Iter object is created
Implementing Class ArrayQueue<E>.Iter (cont.)
private class Iter implements Iterator<E> { private int index; private int count = 0;
public Iter() { index = front; }
@Override public boolean hasNext() { return count < size; } ....
CS340 43
• Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queue interface
count keeps track of the number of items accessed so far
Implementing Class ArrayQueue<E>.Iter (cont.)
private class Iter implements Iterator<E> { private int index; private int count = 0;
public Iter() { index = front; }
@Override public boolean hasNext() { return count < size; } ....
CS340 44
• Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queue interface
hasNext() returns true if count is less than size
Implementing Class ArrayQueue<E>.Iter (cont.)
@Override public E next() { if (!hasNext()) { throw new NoSuchElementException(); } E returnValue = theData[index]; index = (index + 1) % capacity; count+; return returnValue; }
@Override public void remove { throw new UnsupportedOperationException(); } }
CS340 45
• Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queue interface
next() returns the element at position index and increments Iter's fields index and count
Implementing Class ArrayQueue<E>.Iter (cont.)
@Override public E next() { if (!hasNext()) { throw new NoSuchElementException(); } E returnValue = theData[index]; index = (index + 1) % capacity; count+; return returnValue; }
@Override public void remove { throw new UnsupportedOperationException(); } }
CS340 46
• Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queue interface
remove() throws an exception because removing an item other than the first item violates the queue's contract
Comparing the Three Implementations• Computation time
• Comparable in terms of computation time• All operations are O(1)• Although reallocating an array is O(n), its is amortized over n items,
so the cost per item is O(1)
CS340 47
Comparing the Three Implementations (cont.)
Storage Linked-list implementations require more storage due to the extra
space required for the links A double-linked list requires 1.5 times the storage of a single-
linked list A circular array requires half the storage of a single-linked list to
store the same number of elements But a recently reallocated circular array is half empty
CS340 48
The Deque Interface
Section 4.4
CS340 49
Deque Interface• Deque: double-ended queue• Allows insertions and removals from both ends • The Java Collections Framework provides two
implementations of the Deque interface• ArrayDeque • LinkedList
CS340 50
Deque Example
CS340 51
Deque Interface (cont.)• The Deque interface can be used as a
• Queue• Stack
52
Simulating Waiting Lines Using Queues
CS340 53
Simulating Waiting Lines Using Queues Simulation is used to study the performance of a physical
system by using a physical, mathematical, or computer model of the system
CS340 54
Simulating Waiting Lines Using Queues (cont.)
• A branch of mathematics called queuing theory studies such problems
CS340 55
Simulating Google webserver
• You are working for google and need to estimate how many servers you need for the new data center
• The servers receive requests with an exponential arrival process with average 1,000 requests/sec
• The servers serve with average rate 1,800 requests /sec
• You need to provision for peak and low times. • During peak the rate increases to 1,700 req/seq for
duration1 hr• Overnight the server falls to 500 rer/sec for duration 6 hrs
• Simulate 1000 requests on the server.
CS340 56
Simulating Google webserver
• Find:The average waiting time of a requestTo decrease the waiting to half time, would it be better
to use two servers or double the rate of the e-commerce server to 2x?
How many servers do you need to have 0 sec delay?
CS340 57