Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
7 Queue ADTs • Queue concepts. • Queue applications. • A queue ADT: requirements, contract. • Implementations of queues: using arrays, linked lists. • Queues in the Java class library. © 2001, D.A. Watt and D.F. Brown 7-1 Queue concepts • A queue is a first-in-first-out sequence of elements. Elements can added only at one end (the rear of the queue) and removed only at the other end (the front of the queue). • The length of a queue is the number of elements it contains. • An empty queue has length zero. 7-2 Queue concepts (continued) • Illustration (queue of persons): BUS STOP 7-3 Queue applications • Print server maintains a queue of print jobs. • Disk driver maintains a queue of disk input/output requests. • Scheduler (e.g., in an operating system) maintains a queue of processes awaiting a slice of machine time. 7-4 Example 1: demerging (1) • Consider a file of person records, each of which contains a person’s name, gender, date of birth, etc. The records are sorted by date of birth. We are required to rearrange the records such that females precede males but they remain sorted by date of birth within each gender group. • Bad idea: use a sorting algorithm. Time complexity is O(n log n) at best. • Good idea: use a demerging algorithm. Time complexity is O(n). 7-5 Example 1 (2) • Demerging algorithm: To rearrange a file of person records such that females precede males but their order is otherwise unchanged: 1. Make queues females and males empty. 2. Until the input file is empty, repeat: 2.1. Let p be the next person read in from the file. 2.2. If p is female, add p to the rear of females. 2.3. If p is male, add p to the rear of males. 3. Until females is empty, repeat: 3.1. Write out the person removed from the front of females. 4. Until males is empty, repeat: 4.1. Write out the person removed from the front of males. 5. Terminate. 7-6 Queue ADT: requirements • Requirements: 1) It must be possible to make a queue empty. 2) It must be possible to test whether a queue is empty. 3) It must be possible to obtain the length of a queue. 4) It must be possible to add an element at the rear of a queue. 5) It must be possible to remove the front element from a queue. 6) It must be possible to access the front element in a queue without removing it. 7-7 Queue ADT: contract (1) • Possible contract, expressed as a Java interface: public interface Queue { // Each Queue object is a queue whose elements are objects. /////////////// Accessors /////////////// public boolean isEmpty (); // Return true if and only if this queue is empty. public int size (); // Return this queue’s length. public Object getFirst (); // Return the element at the front of this queue. 7-8 Queue ADT: contract (2) • Possible contract (continued): /////////////// Transformers /////////////// public void clear (); // Make this queue empty. public void addLast (Object elem); // Add elem as the rear element of this queue. public Object removeFirst (); // Remove and return the front element of this queue. } 7-9 Implementation of queues using arrays (1) • Consider representing a bounded queue (length maxlen) by: a variable length, containing the current length variables front and rear an array elems of length maxlen, containing the queued elements in elems[front…rear–1]: unoccupied 0 Invariant: Empty queue: 0 front element rear element unoccupied front element element rear–1 element maxlen–1 front=rear maxlen–1 7-10 Implementation using arrays (2) • Animation (with maxlen = 6): After Initially: removing adding Maggie: Ralph: Homer, the front Marge, element: Bart, Lisa: 0 1 2 elems Homer Marge Bart front 0 1 2 rear 054 3 4 5 Lisa Maggie Ralph length 4350 7-11 Implementation using arrays (3) • If we must shift elements along the array, operations addLast and removeFirst will have time complexity O(n). • We can avoid this if we use a “cyclic array” instead of an ordinary array. 7-12 Cyclic arrays • In a cyclic array a of length n, every component has both a successor and a predecessor. In particular: the successor of a[n–1] is a[0] the predecessor of a[0] is a[n–1]. • Alternative ways of visualizing a cyclic array (length 8): 7 0 6 1 5 2 4 0 1 2 3 4 5 3 6 7 7-13 Implementation of queues using cyclic arrays (1) • Representing a bounded queue (length maxlen) by: a variable length, containing the current length variables front and rear a cyclic array elems of length maxlen, containing the queued elements either in elems[front…rear–1] or in elems[front…maxlen–1] and elems[0…rear–1]. 0 Invariant: or: Empty queue: 0 element 0 front element element rear–1 element maxlen–1 rear–1 element front element maxlen–1 element front=rear maxlen–1 7-14 Implementation using cyclic arrays (2) • Animation (with maxlen = 6): After Initially: adding Martin: removing Maggie: Ralph: Nelson: Homer, the front Marge, element: Bart, Lisa: 0 1 2 elems Nelson Homer Martin Marge Bart front 0 1 2 3 rear 21054 3 4 5 Lisa Maggie Ralph length 56430 7-15 Implementation using cyclic arrays (3) • Java implementation: public class ArrayQueue implements Queue { private Object[] elems; private int front, rear, length; /////////////// Constructor /////////////// public ArrayQueue (int maxLength) { elems = new Object[maxLength]; front = rear = length = 0; } 7-16 Implementation using cyclic arrays (4) • Java implementation (continued): /////////////// Accessors /////////////// public boolean isEmpty () { return (length == 0); } public int size () { return length; } public Object getFirst () { if (length == 0) throw …; return elems[front]; } 7-17 Implementation using cyclic arrays (5) • Java implementation (continued): /////////////// Transformers /////////////// public void clear () { for (int i = 0; i < elems.length; i++) elems[i] = null; front = rear = length = 0; } public void addLast (Object elem) { if (length == elems.length) throw …; elems[rear++] = elem; if (rear == elems.length) rear = 0; length++; } 7-18 Implementation using cyclic arrays (6) • Java implementation (continued): public Object removeFirst () { if (length == 0) throw …; Object frontElem = elems[front]; elems[front++] = null; if (front == elems.length) front = 0; return frontElem; } } • Analysis: Most operations have time complexity O(1). Operation clear has time complexity O(maxlen). 7-19 Implementation of queues using SLLs (1) • Represent an (unbounded) queue by: an SLL, whose first node contains the front element, and whose header contains links to the first node (front) and last node (rear). a variable length (optional). Invariant: front rear Empty queue: front rear Illustration: front rear element Homer element Marge element Bart Lisa 7-20 Implementation using SLLs (2) • Java implementation: public class LinkedQueue implements Queue { private SLLNode front, rear; /////////////// Constructor /////////////// public LinkedQueue () { front = rear = null; } /////////////// Accessors /////////////// public boolean isEmpty () { return (front == null); } 7-21 Implementation using SLLs (3) • Java implementation (continued): public int size () { int length = 0; for (SLLNode curr = front; curr != null; curr = curr.succ) length++; return length; } public Object getFirst () { if (front == null) throw …; return front.element; } 7-22 Implementation using SLLs (4) • Java implementation (continued): /////////////// Transformers /////////////// public void clear () { front = rear = null; } public void addLast (Object elem) { SLLNode newest = new SLLNode(elem, null); if (rear != null) rear.succ = newest; else front = newest; rear = newest; } 7-23 Implementation using SLLs (5) • Java implementation (continued): public Object removeFirst () { if (front == null) throw …; Object frontElem = front.element; front = front.succ; if (front == null) rear = null; return frontElem; } } • Analysis: Most operations have time complexity O(1), but size is O(n). However, size too would be O(1) if we used a variable length. 7-24 Queues in the Java class library • Java provides no Queue interface or class as such. • However, the java.util.LinkedList class provides all the above Queue operations. • Illustration: import java.util.LinkedList; LinkedList queue = new LinkedList(); queue.addLast("Homer"); queue.addLast("Marge"); queue.addLast("Bart"); queue.addLast("Lisa"); queue.addLast("Maggie"); System.out.println(busQueue.removeFirst()); 7-25 Example 2: demerging revisited (1) • Recall the demerging algorithm of Example 1. • Implementation: public static void reSortPersons ( BufferedReader input, BufferedWriter output) throws IOException { LinkedList femaleQueue = new LinkedList(); LinkedList maleQueue = new LinkedList(); for (;;) { Person p = readPerson(input); if (p == null) break; // end of input if (p.female) femaleQueue.addLast(p); else maleQueue.addLast(p); } 7-26 Example 2 (2) • Implementation (continued): while (! femaleQueue.isEmpty()) { Person f = femaleQueue.removeFirst(); writePerson(output, f); } while (! maleQueue.isEmpty()) { Person m = maleQueue.removeFirst(); writePerson(output, m); } } 7-27