Queues Data Structures and Design with Java and

  • Slides: 19
Download presentation
Queues Data Structures and Design with Java and JUnit © Rick Mercer 18 -1

Queues Data Structures and Design with Java and JUnit © Rick Mercer 18 -1

A Queue ADT First in first out access w A Queue is another name

A Queue ADT First in first out access w A Queue is another name for waiting line w Example: Submit jobs to a network printer ¾ What gets printed first? · · Print the least recently submitted no priorities given Add new print jobs at the end of the queue w Queues provide First In First Out (FIFO) access to elements could also say Last In Last Out (LILO) 18 -2

The Java Queue class? w Some languages have a Queue class or queue is

The Java Queue class? w Some languages have a Queue class or queue is part of a library that works with the language ¾ Java 1. 4 used class Linked. List to offer FIFO functionality by adding methods add. Last(Object) and Object(get. First) ¾ Java 1. 5 added a Queue interface and several collection classes: Array. Blocking. Queue<E> and Linked. Blocking. Queue<E> w Outline of what we'll do ¾ ¾ Specify a Queue ADT as a Java interface Show a difficult to implement array based implementation 18 -3

Designing a Queue Interface w Queues typically provide these operations ¾ ¾ adds an

Designing a Queue Interface w Queues typically provide these operations ¾ ¾ adds an element at the end of the queue peek returns a reference to the element at the front of the queue removes the element from the front of the queue and returns a reference to the front element is. Empty returns false if there is at least one element in the queue 18 -4

Specify an interface w We will use an interface to describe a queue ADT

Specify an interface w We will use an interface to describe a queue ADT ¾ The interface specifies method names, return types, the type of elements to add, and hopefully comments w interface Our. Queue declares we must be able to add and remove any type of element ¾ Collection class must have <E> to make it a generic type 18 -5

Interface to specify a FIFO Queue import java. util. No. Such. Element. Exception; public

Interface to specify a FIFO Queue import java. util. No. Such. Element. Exception; public interface Our. Queue<E> { // Return true if this queue has 0 elements public boolean is. Empty(); // Store a reference to any object at the end public void add(E new. El); // Return a reference to the object at the // front of this queue public E peek() throws No. Such. Element. Exception; // Remove the reference to the element at the front public E remove() throws No. Such. Element. Exception; } 18 -6

Let Slow. Queue implement the Queue interface w We need to store an Object[]

Let Slow. Queue implement the Queue interface w We need to store an Object[] ¾ an array of Object objects avoids having queue of int and people and cars, and. . . public class Slow. Queue<E> implements Our. Queue<E> { private int back; private Object[] data; //. . . w Now implement all methods of the Our. Queue interface as they are written ¾ plus a constructor with the proper name 18 -7

Bad array type queue w Queue as an array could have ¾ the front

Bad array type queue w Queue as an array could have ¾ the front of the queue is always in data [0] public Slow. Queue(int max) { data = new Object[max]; back = -1; } data[0] null back == -1 data[1] data[2] null data[3] null So far so good. An empty queue 18 -8

First version of add public void add(E element) { // This method will be

First version of add public void add(E element) { // This method will be changed later back++; data[back] = element; } w Send an add message a. Queue. add("a"); data[0] "a" back == 0 data[1] null data[2] data[3] null So far so good. A queue of size 1 18 -9

add another public void add(E element) { // This method will be changed later

add another public void add(E element) { // This method will be changed later back++; data[back] = element; } w Send two more add messages a. Queue. add("b"); a. Queue. add("c"); data[0] "a" back == 2 data[1] "b" data[2] data[3] "c" null So far so good. A Queue of size 3 18 -10

Array Implementation of a Queue w During remove, slide all elements left if size

Array Implementation of a Queue w During remove, slide all elements left if size were 999, then 998 assignments would be necessary Before remove "a" "b" "c" null back A poor remove algorithm After remove "b" "c" back null 18 -11

Effect of queue operation using an array with a "floating" front "a" add("a") add("b")

Effect of queue operation using an array with a "floating" front "a" add("a") add("b") add("c") front remove() "a" "b" "b" "c" "a" "b" ? back "c" "d" back front remove() ? back front add("d") "c" "d" front back 18 -12

What happens next when back equals array. length? add("e") "a" "b" "c" "d" front

What happens next when back equals array. length? add("e") "a" "b" "c" "d" front back indexes the last array index w However, this queue is not full w Where do you place "e"? w back "e" data[0] is available ¾ What code would increment back correctly even when back is referencing the last available array index ¾ ? ________________ ? 18 -13

The Circular Queue w A "circular queue" implementation uses wraparound The queue has "c"

The Circular Queue w A "circular queue" implementation uses wraparound The queue has "c" "d" "e" ¾ either increase back by 1 or set back to 0 "d" "e" "a" front "c" "b" back data[0] add("e") now works in this "circular" queue. It reuses previously used array indexes 18 -14

Implementing a Circular Queue w Still have to work with arrays, not circles ¾

Implementing a Circular Queue w Still have to work with arrays, not circles ¾ In order for the first and last indices to work in a circular manner: · · ¾ increase by one element at a time after largest index in the array, go to zero. back = 0 1 2 3 0. . . could contain code you just wrote on previous slide w But what is an empty queue? ¾ What values should be given to front and back when the queue is constructed? 18 -15

Problem: A full queue can not be distinguished from an empty queue One option

Problem: A full queue can not be distinguished from an empty queue One option is to have the constructor place back one index before front then increment back during add back front a empty a 1 in q front back 3 in q c a d full q b c b back What does back == front imply? An empty or full queue? 18 -16

Corrected Circular Queue w Use this trick to distinguish between full and empty queues

Corrected Circular Queue w Use this trick to distinguish between full and empty queues ¾ The element referenced by front never indexes the front element— the “real” front is located at next. Index(front) private int next. Index(int index) { // Return an int to indicate next position return (index + 1) % data. length; } ¾ For example, use this during peek() return data[next. Index(front)]; 18 -17

Correct Circular Queue Implementation Illustrated back front back "a" empty 1 in q front

Correct Circular Queue Implementation Illustrated back front back "a" empty 1 in q front "a" 2 in q "b" back full q "c" "b" back The front index is always 1 behind the actual front This wastes one array element but it's no big deal 18 -18

Correct Circular remove Implementation Illustrated front "a" full q "c" back 2 in q

Correct Circular remove Implementation Illustrated front "a" full q "c" back 2 in q "b" "c" back "b" 1 in q empty q "c" back front remove three times to make this queue empty front 18 -19