queues1 queues data structures that wait their turn

34
queues 1 Queues Queues Data structures that wait their turn

Upload: angel-breech

Post on 16-Dec-2015

225 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: queues1 Queues Data structures that wait their turn

queues 1

QueuesQueues

Data structures that wait their turn

Page 2: queues1 Queues Data structures that wait their turn

queues 2

Queue characteristicsQueue characteristics

• FIFO: first in, first out

• insertion of items occurs at one end, removal occurs at the other end

• first item inserted is the first item removed; second inserted is second removed, third is third, etc.

Page 3: queues1 Queues Data structures that wait their turn

queues 3

Queue characteristicsQueue characteristics

• Structure is very similar to stack, with much the same considerations -- still subject to overflow and underflow

• Unlike stack, queue is accessible at both ends

• Entry and removal still occur at one end -- but each operation occurs at a different end

Page 4: queues1 Queues Data structures that wait their turn

Java’s Queue interfaceJava’s Queue interface

• Unlike the Stack ADT, the Java API doesn’t provide a full implementation of a generic Queue

• The Queue interface specifies methods for working with a queue, most of which are listed on the next slide

• There are several API classes that implement the interface, but each of these adds methods not specified by the interface

queues 4

Page 5: queues1 Queues Data structures that wait their turn

queues 5

Queue ADT member methodsQueue ADT member methods

• Constructor(s)• Modifiers

– enqueue (insert item at back): add

– dequeue (remove item at front): remove

• Observers– size

– isEmpty

Page 6: queues1 Queues Data structures that wait their turn

Queue implementationsQueue implementations

• The API classes that implement the Queue interface are designed for more sophisticated uses than the simple interface implies

• We can implement a simple queue using either an array or a linked list as the basic structure

queues 6

Page 7: queues1 Queues Data structures that wait their turn

queues 7

Array implementationArray implementation

public class ArrayQueue<E> implements Cloneable {

private E[ ] data; private int manyItems; private int front; private int rear;

Page 8: queues1 Queues Data structures that wait their turn

queues 8

Array implementationArray implementation

public ArrayQueue( ) { final int INITIAL_CAPACITY = 10; manyItems = 0; data = (E[]) new Object[INITIAL_CAPACITY];}// Since queue is empty, front and rear values

// don’t matter

Page 9: queues1 Queues Data structures that wait their turn

queues 9

Array implementationArray implementation

public ArrayQueue(int initialCapacity) { if (initialCapacity < 0) throw new IllegalArgumentException ("initialCapacity is negative: " + initialCapacity); manyItems = 0; data = (E[]) new Object[initialCapacity]; }

Page 10: queues1 Queues Data structures that wait their turn

queues 10

Array implementationArray implementationpublic ArrayQueue<E> clone( ) {

ArrayQueue<E> answer; try { answer = (ArrayQueue<E>) super.clone( ); } catch (CloneNotSupportedException e) { throw new RuntimeException ("This class does not implement Cloneable"); } answer.data = data.clone( ); return answer;

}

Page 11: queues1 Queues Data structures that wait their turn

queues 11

Enqueue and dequeue – not as Enqueue and dequeue – not as simple as they look!simple as they look!

// first attempt at enqueue

public void add (E item) {

if (manyItems == 0) { front = 0; rear = 0; }rear++;

data[rear]=item;

manyItems++;

}

Page 12: queues1 Queues Data structures that wait their turn

queues 12

dequeue (first attempt)dequeue (first attempt)

public E remove( ) { E answer; if (manyItems == 0) throw new NoSuchElementException("Queue underflow"); answer = data[front];

front++;

manyItems--;

return answer;

}

Page 13: queues1 Queues Data structures that wait their turn

queues 13

• Consider a queue with a capacity of 3:

• As items are added, rear approaches capacity:

• As items are removed, front approaches back:

Problems!!!Problems!!!

• Situation: queue isn’t full (manyItems = 0) but attempt to add an item will go beyond array boundary

Page 14: queues1 Queues Data structures that wait their turn

queues 14

Possible solutionPossible solution

• Maintain fixed front of queue:// dequeue method:

answer = data[0];

for (int x=0; x<rear; x++)

data[x]=data[x+1];

• Increases complexity of algorithm considerably -- we’ve gone from O(1) operation in original function to O(N)

Page 15: queues1 Queues Data structures that wait their turn

queues 15

Better solution: circular arrayBetter solution: circular array

• Let front continue to float, but add ability for rear to float as well

• When rear reaches index capacity-1, if queue isn’t full, rear=0

• In effect, the successor of the last array index is the first array index -- array can be thought of as circular

• Can also grow array as necessary

Page 16: queues1 Queues Data structures that wait their turn

queues 16

Circular queue implementationCircular queue implementation

• Add helper function nextIndex as private method of queue class: private int nextIndex(int i) {

if (++i == data.length) return 0; else return i;

}

• Call method from enqueue and dequeue

Page 17: queues1 Queues Data structures that wait their turn

queues 17

New enqueue methodNew enqueue method public void add(E item) {

if (manyItems == data.length) ensureCapacity(manyItems*2 + 1); if (manyItems == 0) { front = 0; rear = 0; } else rear = nextIndex(rear); data[rear] = item; manyItems++; }

Page 18: queues1 Queues Data structures that wait their turn

queues 18

New dequeue methodNew dequeue method

public E remove( ) { E answer; if (manyItems == 0) throw new NoSuchElementException("Queue underflow"); answer = data[front]; front = nextIndex(front); manyItems--; return answer; }

Page 19: queues1 Queues Data structures that wait their turn

Other methodsOther methods

• Besides the queue-specific methods (and clone()), the ArrayQueue implementation includes a few other methods:– ensureCapacity– trimToSize– getCapacity

queues 19

Page 20: queues1 Queues Data structures that wait their turn

queues 20

Invariant for revised queueInvariant for revised queue

• Number of items on queue stored in variable manyItems

• Items are stored in circular array from data[front] to data[rear]

• If queue is empty, manyItems == 0 and the values of front and rear are undefined

Page 21: queues1 Queues Data structures that wait their turn

queues 21

Queue as linked listQueue as linked list

• Implementation using linked list is actually easier• Ironically, the Java API’s LinkedList class

implements the Queue interface, and will be our preferred implementation when we look at queue applications

• Need to decide which end of list is which; easiest implementation is to have the head pointer point to the front of the list, and maintain another pointer to keep track of the back

Page 22: queues1 Queues Data structures that wait their turn

queues 22

Code for linked list queueCode for linked list queue

public class LinkedQueue<E> implements Cloneable{

private int manyNodes; private Node<E> front; private Node<E> rear;

public LinkedQueue( ) { front = null; rear = null; }

Page 23: queues1 Queues Data structures that wait their turn

queues 23

Code for linked list queueCode for linked list queuepublic void add(E item) {

if (isEmpty( )) { front = new Node<E>(item, null); rear = front; } else { rear.addNodeAfter(item); rear = rear.getLink( ); } manyNodes++;

}

Page 24: queues1 Queues Data structures that wait their turn

queues 24

Code for linked list queueCode for linked list queue

public LinkedQueue<E> clone( ) { LinkedQueue<E> answer; Node<E>[ ] cloneInfo; try { answer = (LinkedQueue<E>) super.clone( ); } catch (CloneNotSupportedException e) { throw new RuntimeException ("This class does not implement Cloneable"); }

Page 25: queues1 Queues Data structures that wait their turn

queues 25

Clone method continuedClone method continued

cloneInfo = Node.listCopyWithTail(front); answer.front = cloneInfo[0]; answer.rear = cloneInfo[1]; return answer; }

Page 26: queues1 Queues Data structures that wait their turn

queues 26

Code for linked list queueCode for linked list queue

public boolean isEmpty( ) { return (manyNodes == 0);

}

public int size( ) { return manyNodes;

}

Page 27: queues1 Queues Data structures that wait their turn

queues 27

Code for linked list queueCode for linked list queue

public E remove( ) { E answer; if (manyNodes == 0) throw new NoSuchElementException("Queue underflow"); answer = front.getData( ); front = front.getLink( ); manyNodes--; if (manyNodes == 0) rear = null; return answer;

}

Page 28: queues1 Queues Data structures that wait their turn

Invariant for linked list Invariant for linked list implementationimplementation

• The number of items in the queue is stored in the instance variable manyNodes.

• The items in the queue are stored in a linked list, with the front of the queue stored at the head node, and the rear of the queue at the final node.

• For a non-empty queue, the instance variable front is the head reference of the linked list and the instance variable rear is the tail reference. For an empty queue, both front and rear are the null reference.

queues 28

Page 29: queues1 Queues Data structures that wait their turn

queues2 29

Priority QueuesPriority Queues

• Variation on an ordinary queue -- stores entries and a priority value for each entry

• Elements are dequeued according to priority, highest first

• In case of a tie, priority queue reverts to FIFO behavior

Page 30: queues1 Queues Data structures that wait their turn

queues2 30

PQ implementationPQ implementation

• One strategy is to create an array of ordinary queues – each element in the array would be a queue of

items– all items in any given queue have equal priority

• Array index indicates priority level

Page 31: queues1 Queues Data structures that wait their turn

queues2 31

PQ ImplementationPQ Implementationpublic class PQ<E>{

private ArrayQueue<E>[] queues;public int highest;public int total;public int highCurrent;

public PQ<E> (int h){highest = h;queues = ArrayQueue<E>[] new Object[h+1];total = 0;highCurrent = 0;

}

Page 32: queues1 Queues Data structures that wait their turn

queues2 32

PQ implementationPQ implementation

public int size () {

return total;

}

public boolean is_empty() {

return (total == 0);

}

Page 33: queues1 Queues Data structures that wait their turn

queues2 33

Enqueue functionEnqueue function

template <class Item>void PQ<Item>::PQenqueue(const Item& entry, int priority){

assert (priority <= HIGHEST);// if this is highest priority entry so far, so note:if (priority > highest_current)

highest_current = priority;// place entry in queue:queues[priority].enqueue(entry);// increment count of total entries:count++;

}

Page 34: queues1 Queues Data structures that wait their turn

queues2 34

Dequeue functionDequeue function

template <class Item>

Item PQ<Item>::PQdequeue()

{

assert (PQsize() > 0);

int p = highest_current;

count--;

for(p; p>=0; p--)

if (!queues[p].is_empty())

return queues[p].dequeue();

}