Queues 12/3/2018 Queues © 2014 Goodrich, Tamassia, Goldwasser Queues
The Queue ADT The Queue ADT stores arbitrary objects Queues 12/3/2018 The Queue ADT The Queue ADT stores arbitrary objects Insertions and deletions follow the first-in first-out scheme (FIFO) Insertions are at the rear of the queue and removals are at the front of the queue © 2014 Goodrich, Tamassia, Goldwasser Queues
Main queue operations enqueue(Q, item) // insert in the book Queues 12/3/2018 Main queue operations enqueue(Q, item) // insert in the book inserts an item at the end of the queue item dequeue(Q) // delete in the book removes and returns the item at the front of the queue © 2014 Goodrich, Tamassia, Goldwasser Queues
Auxiliary queue operations Queues 12/3/2018 Auxiliary queue operations item first(Q): returns the element at the front without removing it integer size(Q): returns the number of elements stored boolean isEmpty(Q): indicates whether no elements are stored Boundary cases: Attempting the execution of dequeue or first on an empty queue returns null © 2014 Goodrich, Tamassia, Goldwasser Queues
Example Operation Output Q enqueue(Q,5) – (5) enqueue(Q,3) – (5, 3) dequeue(Q) 5 (3) enqueue(Q,7) – (3, 7) dequeue(Q) 3 (7) first(Q) 7 (7) dequeue(Q) 7 () dequeue(Q) null () isEmpty(Q) true () enqueue(Q,9) – (9) enqueue(Q,7) – (9, 7) size(Q) 2 (9, 7) enqueue(Q,3) – (9, 7, 3) enqueue(Q,5) – (9, 7, 3, 5) dequeue(Q) 9 (7, 3, 5) © 2014 Goodrich, Tamassia, Goldwasser Queues
Applications of Queues Direct applications Waiting lists, bureaucracy Access to shared resources (e.g., printer) Multiprogramming Indirect applications Auxiliary data structure for algorithms Component of other data structures © 2014 Goodrich, Tamassia, Goldwasser Queues
wrapped-around configuration Array-based Queue Use an array of size N in a circular fashion Two variables keep track of the front and size f index of the front element sz number of stored elements When the queue has fewer than N elements, array location r = (f + sz) mod N is the first empty slot past the rear of the queue normal configuration Q 1 2 r f wrapped-around configuration Q 1 2 f r © 2014 Goodrich, Tamassia, Goldwasser Queues
Why “circular” array? Why not “regular” array? the first item on the queue is always the first item in the array? front rear 5 3 9 7 © 2014 Goodrich, Tamassia, Goldwasser Queues
Can we use a linked list to implement a queue? What are the tradeoffs? © 2014 Goodrich, Tamassia, Goldwasser Queues
Queue Operations Algorithm size(Q) return Q->sz Algorithm isEmpty(Q) return (Q->sz == 0) Q 1 2 r f Q 1 2 f r © 2014 Goodrich, Tamassia, Goldwasser Queues
Queue Operations (cont.) Algorithm enqueue(Q, item) if size(Q) = N then print error else r (Q->f + Q->sz) mod N Q->data[r] item Q->sz (Q->sz + 1) Operation enqueue throws an exception if the array is full This exception is implementation-dependent Q 1 2 r f Q 1 2 f r © 2014 Goodrich, Tamassia, Goldwasser Queues
Queue Operations (cont.) Note that operation dequeue returns null if the queue is empty Algorithm dequeue(Q) if isEmpty(Q) then return null else item Q->data[Q->f] Q->f (Q->f + 1) mod N Q->sz (Q->sz - 1) return o Q 1 2 r f Q 1 2 f r © 2014 Goodrich, Tamassia, Goldwasser Queues
Worst-case time complexity N items on the queue Operation “Circular Array” “Normal” Array Linked List (head & tail) enqueue dequeue © 2014 Goodrich, Tamassia, Goldwasser Queues
Worst-case time complexity N items on the queue Operation “Circular” Array “Normal” Array Linked List (head & tail) enqueue O(1) dequeue O(N) © 2014 Goodrich, Tamassia, Goldwasser Queues
Application: Round Robin Schedulers We can implement a round robin scheduler using a queue Q by repeatedly performing the following steps: e = dequeue(Q) Service item e enqueue(Q, e) Queue Dequeue Enqueue Shared Service © 2014 Goodrich, Tamassia, Goldwasser Queues