queues what are queues? creating a queue enqueuing and dequeuing testing for an empty queue

32
QUEUES • What are Queues? • Creating a Queue • Enqueuing and Dequeuing • Testing for an Empty Queue

Upload: sheena-wilcox

Post on 14-Jan-2016

222 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

QUEUES

• What are Queues?

• Creating a Queue

• Enqueuing and Dequeuing

• Testing for an Empty Queue

                           

      

Page 2: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 2 of 32

Queues

• Similar to stacks, but items are removed in different order

• Useful in different situations:– stacks used for activation records– queues used for event processing

• Information retrieved in same order in which it was stored– FIFO: first in, first out

• Examples:– standing in line

• Like stacks, queues store Objects– again, use generics to restrict class types of data

passed to queue

October 27, 2005

Page 3: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 3 of 32

Enqueuing and Dequeuing

• Enqueuing: adds a node

• Dequeuing: removes a node

BEFORE ENQUEUING AFTER ENQUEUING

person removed from queue

BEFORE DEQUEUING AFTER DEQUEUING

head of queue

tail of queue

person to add

head of queue

head of queue

head of queue

tail of queue

tail of queue

tail of queue

1 2 3 4 1 2 3 4

1 2 3 41 2 3 4

Page 4: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 4 of 32

Syntax: The Movie Line

• A movie line queue may be instantiated to only accept object of type person:

• Right now Person only stores _myName– subclasses might store more information (phone number, favorite foods, pictures,

etc.)

• Different subclasses of people can be stored in a queue– we use generics to only allow Persons– Men and Women could be subclasses of Person– both types of people would be able to stand in our line

• Number of plates on dispenser can vary from 0 to . . .

public class Person { private String _myName; public Person (String name) { _myName = name; } public String getName() { return _myName; }}

October 27, 2005

Page 5: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 5 of 32

Special Notes

• In a stack, everything is added and removed from top

• Bottom:– was never removed– handled special cases when stack was empty

• Queues require two special nodes: one to mark head of queue and one to mark tail

• Queue dequeues via head node; enqueues via tail node. Neither head nor tail can be removed

• Unlike bottom of stack, which had no references, tail node needs to communicate with last internal node of queue in order to give it reference to newly enqueued node

• Head node needs reference to next node in order to dequeue it

October 27, 2005

Page 6: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 6 of 32

The Complete Queue

• Let’s look at a complete queue. Note that Queue class contains references to head and tail nodes– head and tail are permanent parts of queue

HeadNodeNode _next

InternalNode

ElementType _dataNode _next

InternalNode

ElementType _dataNode _next

InternalNode

ElementType _dataNode _next

Queue

HeadNode _headTailNode _tail

TailNodeNode _prev

...

...

...

October 27, 2005

Page 7: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 7 of 32

Example: Enqueue (1 of 3)

• Let’s look at an example of enqueuing. This is our empty queue:

• Note that head and tail nodes point to each other

HeadNodeNode _next

Queue

HeadNode _headTailNode _tail

TailNodeNode _prev

October 27, 2005

Page 8: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 8 of 32

Example: Enqueue (2 of 3)

• Here’s our queue right BEFORE one enqueue:

• Note: We haven’t forgotten about Queue class that contains head and tail; we just didn’t draw it for simplicity

• A new Internal Node is instantiated, “Mike” is the data stored in _myName

• References that have been newly set or changed and new instances shown in red

HeadNodeNode _next

TailNodeNode _prev

InternalNode

ElementType _dataNode _next

PersonMike

October 27, 2005

Page 9: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 9 of 32

Example: Enqueue (3 of 3)

• Here’s our queue after the second enqueue (new node is added at end):

• Once again, reference in red are the only ones queue needs to change

HeadNodeNode _next

TailNodeNode _prev

InternalNode

ElementType _dataNode _next

PersonSara

InternalNode

ElementType _dataNode _next

PersonMike

October 27, 2005

Page 10: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 10 of 32

Let’s Dequeue

• Note here’s our list after one dequeue (node closest to head node is removed):

• This looks simpler than enqueue of empty queue: only one reference needed to change

HeadNodeNode _next

TailNodeNode _prev

InternalNode

ElementType _dataNode _next

PersonSara

October 27, 2005

InternalNode

ElementType _dataNode _next

PersonMike

Garbage Collected!

Page 11: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 11 of 32

A Tricky Dequeue

• Let’s dequeue the last internal node:

• Now there are two links that need to change:

HeadNodeNode _next

TailNodeNode _prev

October 27, 2005

InternalNode

ElementType _dataNode _next

PersonSara

• boundary case: dequeue will need to behave differently when removing last internal node

Garbage Collected!

Page 12: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 12 of 32

Empty?

• We also need to be able to check if Queue representing our movie line is empty

• In stack, isEmpty() was easy to write -- Stack asked top node and InternalNode returned false; Bottom returned true

• Queue will always refer to HeadNode and TailNode only. How can we check isEmpty()?

• Queue will ask HeadNode, which will in turn ask _next node. As before, InternalNode will return false and TailNode will return true

• Very similar to Stack, but with one extra level of delegation

October 27, 2005

Page 13: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 13 of 32

Nodes

• Before we can build queue, we need to define smart nodes which make it up

• Once again, we need generic superclass from which all concrete nodes will inherit

• enqueue and dequeue need to reset some references. We will define set methods for all nodes to help them do this

• Three different types of nodes hold different references and will react very differently to these methods, but– we still want to be able to call these methods

using reference to generic node– so, we have to declare their common methods in

superclass - polymorphism again

October 27, 2005

Page 14: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 14 of 32

Generic Nodes• Code for generic node:

• setNext and setPrevious are empty methods which do nothing by default

• isEmpty will return true for tail node, false for internal nodes

• Node superclass declares dequeue message, but not enqueue:– in stack, Node declared pop message, but not push

– every type of object in queue responds differently to dequeue message so is declared abstract in superclass

– enqueue is specific to TailNode so declare it there

// generic Queue Nodepublic abstract class Node<ElementType> { public void setNext(Node<ElementType>

newNextNode) {} public void setPrevious(Node<ElementType>

newPrevNode) {} abstract public boolean isEmpty(); abstract public Node<ElementType> dequeue

(ObjectHolder result);}

October 27, 2005

Page 15: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 15 of 32

Head Node• Head node is responsible for starting dequeue

because queue removes things from front:

• HeadNode inherits setPrevious method but does not redefine it, since head node has no _previous reference; instead redefines setNext which it uses to jump around dequeued node to reference new first node

• We’ve left most of these methods undefined; we’ll define them later

public class HeadNode<ElementType> extends Node { private Node<ElementType> _next; public HeadNode() {

... } // methods redefined from superclass public Node<ElementType> dequeue (Holder<ElementType> result) {...} public boolean isEmpty() {...} public void setNext(Node<ElementType>

newNextNode){ _next = newNextNode; }}

October 27, 2005

Page 16: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 16 of 32

Tail Node• Conversely, tail node handles enqueue:

• TailNode inherits setNext method but does not redefine it, since tail node has no _next reference; instead redefines setPrevious

• Since tail node responds to dequeue message, must redefine it

• We will define the rest of these methods later

public class TailNode<ElementType> extends Node {

private Node<ElementType> _prev; public TailNode(Node<ElementType>

newPrevNode) {...

} // method specific to TailNode public void enqueue(ElementType newData)

{...} // methods redefined from superclass public Node dequeue

(Holder<ElementType> result) {...} public void setPrevious(Node<ElementType>

newPrevNode) { _prev = newPrevNode; }}

October 27, 2005

Page 17: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 17 of 32

Internal Nodes

• Internal nodes need references to data they store and to next node in queue:

• Like head node, internal nodes redefine setNext method

• setPrevious does nothing (as in superclass), so it doesn’t need to be redefined

public class InternalNode<ElementType> extends Node {

private ElementType _data; private Node<ElementType> _next; public InternalNode(ElementType newData,

Node<ElementType> newNextNode) {...} // methods redefined from superclass public Node<ElementType> dequeue

(Holder<ElementType> result) {...} public void setNext(Node<ElementType>

newNextNode) { _next = newNextNode; }}

October 27, 2005

Page 18: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 18 of 32

Queue • Now that we know what nodes look like, we

can begin to code our queue:

• Queue has to keep references to both HeadNode and TailNode so it can tell _tail to enqueue and _head to dequeue

public class Queue<ElementType> { private Node<ElementType> _head; private TailNode<ElementType> _tail; // instantiates HeadNode and TailNode public Queue() { //note asymmetric reference setting! why? _head = new HeadNode<ElementType>(); //set in constructor _tail = new TailNode<ElementType>(_head); //set explicitly _head.setNext(_tail); } public void dequeue() { // code to follow... } public boolean isEmpty() { // code to follow... } public void enqueue(ElementType newData) { // code to follow... }}

October 27, 2005

Page 19: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 19 of 32

Node Constructors• So far, we’ve defined Queue to construct

instances of HeadNode and TailNode. InternalNodes will be created during enqueuing as they were during pushes of stackpublic class HeadNode<ElementType> extends Node { //head doesn’t set its _next here public HeadNode() { super(); } //rest of class . . . }

public class TailNode<ElementType> extends Node { //tail does set its _previous here public TailNode(Node<ElementType> newPrevNode){ super(); _prev = newPrevNode; } //rest of class . . .}

public class InternalNode<ElementType> extends Node {

public InternalNode(ElementType newData, Node<ElementType> newNextNode) { super(); _next = newNextNode; _data = newData; } //rest of class . . .}

October 27, 2005

Page 20: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 20 of 32

Enqueue

• Queue delegates enqueue message to tail node, telling it to add new internal node before it:

• TailNode’s enqueue method:– creates new internal node, passing it data to store and

reference to tail which it will store in its _next– reassigns _next reference of its previous node to point

to new node– resets its own _prev reference to new node

• Let’s see a picture....

public class Queue<ElementType> { public void enqueue(ElementType newData) { _tail.enqueue(newData);} . . .}

public class TailNode<ElementType> extends Node{ public void enqueue(ElementType newData) { InternalNode<ElementType> newPrevNode = new

InternalNode<ElementType>(newData, this); _prev.setNext(newPrevNode); _prev = newPrevNode; } . . .}

October 27, 2005

Page 21: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 21 of 32

Example: Enqueue (1 of 2)

• Before enqueue:

• Tail creates new internal node, sending it references to data and itself; reference to new node stored in newPrevNode

HeadNodeNode _next

TailNodeNode _prev

InternalNode

ElementType _dataNode _next

PersonSara

HeadNodeNode _next

TailNodeNode _prev

PersonSara

newData to enqueue

InternalNode<ElementType> newPrevNode =

newPrevNode

October 27, 2005

new InternalNode<ElementType>(newData, this);

Page 22: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 22 of 32

Example: Enqueue (2 of 2)

• Tail tells its previous node (head in this case) to reset its _next reference to newPrev

• Tail resets its own _prev reference

HeadNodeNode _next

TailNodeNode _prev

InternalNode

ElementType _dataNode _next

PersonSara

HeadNodeNode _next

TailNodeNode _prev

InternalNode

ElementType _dataNode _next

PersonSara

newPrevNode

newPrevNode

October 27, 2005

_prev.setNext(newPrevNode);

_prev = newPrevNode;

Page 23: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 23 of 32

Syntax: Dequeue (1 of 3)

• dequeue removes internal node at head of queue and returns its data

• Queue’s dequeue method:– creates Holder (remember from stacks lecture --

why we use one?)– sends dequeue message to head node, passing

it reference to Holder– returns data stored in Holder

public class Queue<ElementType> { public ElementType dequeue() { Holder<ElementType> result =

new Holder<ElementType>(); _head.dequeue(result); return result.getObject(); } . . .}

October 27, 2005

Page 24: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 24 of 32

Syntax: Dequeue (2 of 3)

• HeadNode passes on dequeue message to next node in list, either internal or tail node:

• Just as with Stack’s internal nodes, Queue’s InternalNodes update Holder to reference their _data and return reference to their next node:

public class HeadNode<ElementType> extends Node{ // next (internal) node assigns its data to // result and returns its next; tail “no-ops” public Node<ElementType> dequeue(

Holder<ElementType> result) { _next = _next.dequeue(result); // tell next to point its previous to me. // Only for tailNode; internal node no-ops _next.setPrevious(this); return this; } . . .}

public class InternalNode<ElementType> extends Node {

public Node<ElementType> dequeue( Holder<ElementType> result) {

result.setObject(_data); return _next; }. . .}

October 27, 2005

Page 25: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 25 of 32

Syntax: Dequeue (3 of 3)

• TailNodes don’t have _data or _next reference, so they just return reference to themselves:

• Note similarities to Stack!

• Now, let’s hand simulate our code . . .

public class TailNode<ElementType> extends Node{ public Node<ElementType> dequeue( Holder<ElementType> result) { return this; } . . .}

October 27, 2005

Page 26: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 26 of 32

Example: Dequeue (1 of 3)

From class Queue:result = new Holder<ElementType>();

HeadNodeNode _next

TailNodeNode _prev

InternalNode

ElementType _dataNode _next

PersonSara

InternalNode

ElementType _dataNode _next

PersonMike

Holder

ElementType _data

null

result

October 27, 2005

Page 27: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 27 of 32

Example: Dequeue (2 of 3)

From HeadNode: _next = _next.dequeue(result);From InternalNode: result.setObject(_data);From InternalNode: return _next;From HeadNode: _next.setPrevious(this);

Let’s see this simulated:

HeadNodeNode _next

TailNodeNode _prev

InternalNode

ElementType _dataNode _next

PersonSara

InternalNode

ElementType _dataNode _next

PersonMike

Holder

ElementType _data

result

Internal Node about to be garbage collected

October 27, 2005

Page 28: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 28 of 32

Example: Dequeue (3 of 3)

• What happens if we call dequeue on empty queue?

• Queue will not change– Holder will contain no data after TailNode’s dequeue method returns itself

– HeadNode’s _next reference will still point to tail because tail’s dequeue method returns reference to itself

• Cleaner code might be to check if queue is empty before dequeue-ing

October 27, 2005

Page 29: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 29 of 32

Empty (1 of 2)

• As with stack, queue does not know if it is isEmpty, so it must delegate:

• HeadNode does not know either, so must ask _next node:

public class Queue<ElementType> { public boolean isEmpty() { return _head.isEmpty(); } . . .}

public class HeadNode<ElementType> extends Node{ public boolean isEmpty() { return _next.isEmpty(); } . . .}

October 27, 2005

Page 30: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 30 of 32

Empty (2 of 2)

• If HeadNode sends isEmpty message to InternalNode, then queue has at least one element:

• If HeadNode sends isEmpty message to TailNode, then queue must be empty (no InternalNodes):

public class InternalNode<ElementType> extends Node {

public boolean isEmpty() { return false; } . . .}

public class TailNode<ElementType> extends Node{ public boolean isEmpty() { return true; } . . .}

October 27, 2005

Page 31: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 31 of 32

And we’re done!

HAPPY QUEUING!JUST QUEUE IT!

QUEUE, BABY, QUEUE

Q

October 27, 2005

Page 32: QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue

© 2006 Pearson EducationQueues 32 of 32 October 27, 2005