720 likes | 855 Views
Chapter 4. Queues. Chapter Objectives. Q ueue? Operations Insertion (offer and add) Removal (remove and poll) Accessing (peek and element) Queue implementation Single linked list Circular array Double linked list Deque ?. Queue. Stack—LIFO Queue--FIFO. Queue Abstract Data Type.
E N D
Chapter 4 Queues
Chapter Objectives • Queue? • Operations • Insertion (offer and add) • Removal (remove and poll) • Accessing (peek and element) • Queue implementation • Single linked list • Circular array • Double linked list • Deque?
Queue • Stack—LIFO • Queue--FIFO
Queue Abstract Data Type Section 4.1
Queue Abstract Data Type • Queue example • How a person is served? • Add a new element?
Queue Examples • OS task/process queue • Print queue
Print Stack? • Stack -- LIFO • What’s the problem with Print Stack?
Another Example: Graph Traversal • Network graph (node, links) • Breadth-First traversal
Queue LinkedList Implementation • LinkedList • Inserting and removing easily. • Java 5.0 Queue implementation Queue<String> names = new LinkedList<String>();
Example-Maintaining a Queue of Customers Section 4.2
Maintaining a Queue of Customers • Maintaining Methods • insert a new customer • display the customer • remove the customer • display the length • Special determination
Designing a Queue of Customers • JOptionPane.showOptionDialog() menu • Use a queue the data structure • MaintainQueue class • a Queue<String> component customers
Maintain a Queue of Customers Algorithm for processCustomers • while the user is not finished • Display the menu and get the selected operation • Perform the selected operation Algorithm for determining the position of a Customer • Get the customer name • Set the count of customers ahead of this one to 0 • for each customer in the queue • if the customer is not the one sought • increment the counter • else • display the count of customers and exit the loop • if all the customers were examined without success • display a message that the customer is not in the queue
Implementing a Queue of Customers • Listing 4.1&4.2 MaintainQueue & ProcessCustomers
Implementing the Queue Interface Section 4.3
1-Use Double-Linked List • Insertion and removal is O(1) • Problem: • More methods are available • Solution: • Create a new class with a LinkedList component • Only implement the methods for Queue
2-Use a Single-Linked List • Insertions –at the end of a queue • One reference to the last nodeO(1) performance • Removal-- from the front of a queue • Listing 4.3 ListQueue
3-Use a Circular Array • Time efficiency OK • a single- or double-linked list • Space efficiency– NOT OK • Due to refernces • Array Implementation • Insertion at rearO(1) • Removal from the frontO(n) • Removal from rear O(1) • Insertion at the front O(n)
Initializing ArrayQueue q = new ArrayQueue(5); size = 0 front = 0 capacity = 5 public ArrayQueue(int initCapacity) { capacity = initCapacity; theData = (E[])new Object[capacity]; front = 0; rear = capacity – 1; size = 0; } rear = 4
add (‘*’) q.offer('*'); size = 0 1 front = 0 * capacity = 5 public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true; } rear = 4 rear = 0
add ‘+’ q.offer('+'); size = 1 2 front = 0 * capacity = 5 + public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true; } rear = 1 rear = 0
add ‘/’ q.offer('/'); size = 2 3 front = 0 * capacity = 5 + / public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true; } rear = 1 rear = 2
add ‘-’ q.offer('-'); size = 3 4 front = 0 * capacity = 5 + / public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true; } - rear = 3 rear = 2
add ‘A’ q.offer('A'); size = 4 5 front = 0 * capacity = 5 + / public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true; } - rear = 4 rear = 3 A
poll next = q.poll(); size = 5 4 front = 0 front = 1 * capacity = 5 + / public E poll() { if (size == 0) { return null } E result = theData[front]; front = (front + 1) % capacity; size--; return result; } - rear = 4 A result = '*'
Poll again next = q.poll(); size = 4 3 front = 1 front = 2 * capacity = 5 + / public E poll() { if (size == 0) { return null } E result = theData[front]; front = (front + 1) % capacity; size--; return result; } - rear = 4 A result = '+'
add ‘B’ q.offer('B'); size = 3 4 front = 2 * B capacity = 5 + / public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true; } - rear = 4 rear = 0 A
add ‘C’ q.offer('C'); size = 4 5 front = 2 B capacity = 5 + C / public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true; } - rear = 0 rear = 1 A
add ‘D’ q.offer('D'); size = 5 front = 2 B capacity = 5 + C / public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true; } - rear = 1 A
Reallocate theData B q.offer('D'); + C size = 5 front = 2 front = 2 B / capacity = 5 - + C A / 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; } - rear = 1 rear = 1 A newCapacity = 10
Reallocate newData theData i = 0 B q.offer('D'); + C size = 5 front = 2 j = 2 / capacity = 5 - A 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; } rear = 1 newCapacity = 10
Copy data newData theData i = 1 i = 0 B / q.offer('D'); + C size = 5 front = 2 j = 2 / / capacity = 5 j = 3 - A 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; } rear = 1 newCapacity = 10
Copy data newData theData i = 2 i = 1 / B q.offer('D'); + C - size = 5 front = 2 / capacity = 5 j = 3 - - A j = 4 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; } rear = 1 newCapacity = 10
Copy data newData theData i = 3 i = 2 / j = 0 B q.offer('D'); + C - size = 5 front = 2 / A capacity = 5 - A A j = 4 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; } rear = 1 newCapacity = 10
Copy data newData theData i = 4 i = 3 / B B j = 0 q.offer('D'); j = 1 + C - size = 5 front = 2 / A capacity = 5 - B A 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; } rear = 1 newCapacity = 10
Copy data newData theData i = 5 i = 4 / B q.offer('D'); j = 1 + C C - size = 5 front = 2 j = 2 / A capacity = 5 - B A C 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; } rear = 1 newCapacity = 10
Initialize new queue newData theData i = 5 / B q.offer('D'); + C C - size = 5 rear = 4 front = 0 front = 2 j = 2 / A 10 capacity = 5 - B A C 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; } rear = 1 newCapacity = 10
Add‘D’ theData / q.offer('D'); - size = 5 6 rear = 4 front = 0 rear = 5 A 10 capacity = 5 B C public boolean offer(E item) { if (size == capacity) { reallocate(); } size++; rear = (rear + 1) % capacity; theData[rear] = item; return true; } D
Implementing a Queue Using a Circular Array -All Code • Listing 4.4 ArrayQueue
Implementing Class ArrayQueue<E>.Iter private class Iter implements Iterator<E> { private int index; private int count = 0; public Iter() { index = front; } @Override public boolean hasNext() { return count < size; } .... • Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queueinterface
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; } .... • Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queueinterface indexstores 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; } .... • Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queueinterface 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; } .... • Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queueinterface countkeeps 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; } .... • Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queueinterface hasNext() returns true if count is less than size
Implementing Class ArrayQueue<E>.Iter(cont.) @Override public E next() { if (!hasNext()) { throw newNoSuchElementException(); } E returnValue = theData[index]; index = (index + 1) % capacity; count+; return returnValue; } @Override public void remove { throw newUnsupportedOperationException(); } } • Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queueinterface 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 newNoSuchElementException(); } E returnValue = theData[index]; index = (index + 1) % capacity; count+; return returnValue; } @Override public void remove { throw newUnsupportedOperationException(); } } • Just as for class ListQueue<E>, we must implement the missing Queue methods and an inner class Iter to fully implement the Queueinterface remove() throws an exception because removing an item other than the first item violates the queue's contract
Time comparison • Computation time • All three implementations are comparable in terms of computation time • All operations are O(1) regardless of implementation • Although reallocating an array is O(n), it is amortized over n items, so the cost per item is O(1)