• No results found

CSCI 136 Data Structures & Advanced Programming. Queues

N/A
N/A
Protected

Academic year: 2021

Share "CSCI 136 Data Structures & Advanced Programming. Queues"

Copied!
78
0
0

Loading.... (view fulltext now)

Full text

(1)

CSCI 136

Data Structures &

Advanced Programming

(2)

tail head

Queues

A Queue is a collection of elements, but access

is restricted to the “head” and “tail”

(3)

tail head

Queues

A Queue is a collection of elements, but access

is restricted to the “head” and “tail”

(4)

tail head

Queues

A Queue is a collection of elements, but access

is restricted to the “head” and “tail”

Many “real-world” examples, including:

(5)

tail head

Queues

A Queue is a collection of elements, but access

is restricted to the “head” and “tail”

Many “real-world” examples, including:

•Lines at movie theater, grocery store, etc.

•OS event queue (keeps keystrokes, mouse clicks, etc., in order)

(6)

tail head

Queues

A Queue is a collection of elements, but access

is restricted to the “head” and “tail”

Many “real-world” examples, including:

•Lines at movie theater, grocery store, etc.

•OS event queue (keeps keystrokes, mouse clicks, etc., in order)

(7)

tail head

Queues

A Queue is a collection of elements, but access

is restricted to the “head” and “tail”

Many “real-world” examples, including:

•Lines at movie theater, grocery store, etc.

•OS event queue (keeps keystrokes, mouse clicks, etc., in order)

•Printers

(8)

The Structure5 Universe (+ Linear!)

Interface Abstract Class Class

List Structure Linear AbstractStructure AbstractLinear AbstractList AbstractStack

Vector SinglyLinkedList DoublyLinkedList AbstractQueue

(9)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(10)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

(11)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

(12)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(13)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(14)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(15)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(16)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(17)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(18)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(19)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(20)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(21)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(22)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(23)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(24)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(25)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(26)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(27)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(28)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(29)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(30)

Stacks vs. Queues

•Stacks are LIFO (Last In First Out) •Queues are FIFO (First In First Out)

(bottom) (tail) (head)

add

add remove

(31)

Stacks vs. Queues

•Both Stacks and Queues linear data structures

(implement Linear, extend abstract classes that extend AbstractLinear),

(32)

Stacks vs. Queues

•Both Stacks and Queues linear data structures

(implement Linear, extend abstract classes that extend AbstractLinear),

•Like Stacks, Queues have their own terminology,

(33)

Stacks vs. Queues

•Both Stacks and Queues linear data structures

(implement Linear, extend abstract classes that extend AbstractLinear),

•Like Stacks, Queues have their own terminology,

which can be mapped to Linear interface methods:

(34)

Stacks vs. Queues

•Both Stacks and Queues linear data structures

(implement Linear, extend abstract classes that extend AbstractLinear),

•Like Stacks, Queues have their own terminology,

which can be mapped to Linear interface methods:

• enqueue: insert value at back of queue

(35)

Stacks vs. Queues

•Both Stacks and Queues linear data structures

(implement Linear, extend abstract classes that extend AbstractLinear),

•Like Stacks, Queues have their own terminology,

which can be mapped to Linear interface methods:

• enqueue: insert value at back of queue

• dequeue: remove value from front of queue,

(36)

Stacks vs. Queues

•Also like

Stacks

,

Queues

can be

(37)

Stacks vs. Queues

•Also like

Stacks

,

Queues

can be

implemented:

By using existing structures (e.g., Vector,

LinkedList

), or

(38)

Stacks vs. Queues

•Also like

Stacks

,

Queues

can be

implemented:

By using existing structures (e.g., Vector,

LinkedList

), or

As “stripped down” versions of those

structures

We can implement a stacks/queues using the same underlying organization as those structures, but with reduced/simplified/optimized implementations

(39)

The Structure5 Universe (+ Stacks!)

Interface Abstract Class Class

List Structure Linear AbstractStructure AbstractLinear AbstractList AbstractStack

Vector SinglyLinkedList DoublyLinkedList AbstractQueue

Stack Queue

(40)

The Structure5 Universe (+ Queues!)

Interface Abstract Class Class

List Structure Linear AbstractStructure AbstractLinear AbstractList AbstractStack

Vector SinglyLinkedList DoublyLinkedList AbstractQueue

Stack Queue

(41)

Queue Interface

public interface Queue<E> extends Linear<E> { public void enqueue(E item);

public E dequeue(); public E peek(); public int size(); }

Also some others like add(), remove(), getFirst()

(42)

Implementing Queues

As with Stacks, we have three options: QueueArray

QueueVector

(43)

Implementing Queues

As with Stacks, we have three options: QueueArray

class QueueArray<E> implements Queue<E> {

protected Object[] data; //can’t instantiate E[] int head;

int count; // can be used to determine tail...

QueueVector

(44)

Implementing Queues

As with Stacks, we have three options: QueueArray

class QueueArray<E> implements Queue<E> {

protected Object[] data; //can’t instantiate E[] int head;

int count; // can be used to determine tail... }

QueueVector

(45)

Implementing Queues

As with Stacks, we have three options: QueueArray

class QueueArray<E> implements Queue<E> {

protected Object[] data; //can’t instantiate E[] int head;

int count; // can be used to determine tail... }

QueueVector

class QueueVector<E> implements Queue<E> { protected Vector<E> data;

}

(46)

Implementing Queues

As with Stacks, we have three options: QueueArray

class QueueArray<E> implements Queue<E> {

protected Object[] data; //can’t instantiate E[] int head;

int count; // can be used to determine tail... }

QueueVector

class QueueVector<E> implements Queue<E> { protected Vector<E> data;

}

QueueList

class QueueList<E> implements Queue<E> {

protected List<E> data; //uses a CircularList }

(47)

Tradeoffs:

• QueueArray:

• QueueVector: • QueueList:

(48)

Tradeoffs:

• QueueArray:

• enqueue is O(1): (rough idea) data[tail] = item;

• QueueVector: • QueueList:

(49)

Tradeoffs:

• QueueArray:

• enqueue is O(1): (rough idea) data[tail] = item;

• dequeue is O(1): (rough idea) data[head] = null; head++;

• QueueVector: • QueueList:

(50)

Tradeoffs:

• QueueArray:

• enqueue is O(1): (rough idea) data[tail] = item;

• dequeue is O(1): (rough idea) data[head] = null; head++; • Faster operations, but limited size

• QueueVector: • QueueList:

(51)

Tradeoffs:

• QueueArray:

• enqueue is O(1): (rough idea) data[tail] = item;

• dequeue is O(1): (rough idea) data[head] = null; head++; • Faster operations, but limited size

• QueueVector:

• enqueue is O(1): uses vec.addLast

(52)

Tradeoffs:

• QueueArray:

• enqueue is O(1): (rough idea) data[tail] = item;

• dequeue is O(1): (rough idea) data[head] = null; head++; • Faster operations, but limited size

• QueueVector:

• enqueue is O(1): uses vec.addLast

• dequeue is O(n): uses vec.removeFirst

(53)

Tradeoffs:

• QueueArray:

• enqueue is O(1): (rough idea) data[tail] = item;

• dequeue is O(1): (rough idea) data[head] = null; head++; • Faster operations, but limited size

• QueueVector:

• enqueue is O(1): uses vec.addLast

• dequeue is O(n): uses vec.removeFirst

• QueueList:

(54)

Tradeoffs:

• QueueArray:

• enqueue is O(1): (rough idea) data[tail] = item;

• dequeue is O(1): (rough idea) data[head] = null; head++; • Faster operations, but limited size

• QueueVector:

• enqueue is O(1): uses vec.addLast

• dequeue is O(n): uses vec.removeFirst

• QueueList:

• enqueue is O(1): uses lst.addLast

(55)

Tradeoffs:

• QueueArray:

• enqueue is O(1): (rough idea) data[tail] = item;

• dequeue is O(1): (rough idea) data[head] = null; head++; • Faster operations, but limited size

• QueueVector:

• enqueue is O(1): uses vec.addLast

• dequeue is O(n): uses vec.removeFirst

• QueueList:

• enqueue is O(1): uses lst.addLast

• dequeue is O(1): uses lst.removeFirst

• Note: uses a Circularly Linked List so we have fast head and tail operations, but we only store one reference per node (next)

(56)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

(57)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

(58)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

• How to implement?

(59)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

• How to implement?

• enqueue(item), dequeue(), size()

tail head

(60)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

• How to implement?

• enqueue(item), dequeue(), size()

tail head

A B

head points to front of queue; tail points to next empty space (where next

(61)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

• How to implement?

• enqueue(item), dequeue(), size()

tail head A B enque ue (C )

head points to front of queue; tail points to next empty space (where next

(62)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

• How to implement?

• enqueue(item), dequeue(), size()

tail head A B tail head A B C enque ue (C )

head points to front of queue; tail points to next empty space (where next

(63)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

• How to implement?

• enqueue(item), dequeue(), size()

tail head A B tail head A B C enque ue (C )

head points to front of queue; tail points to next empty space (where next

item will be added)

head and tail “wrap around” array; when queue is full,

(64)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

• How to implement?

• enqueue(item), dequeue(), size()

tail head A B tail head A B C enque ue (C ) de que ue ()

head points to front of queue; tail points to next empty space (where next

item will be added)

head and tail “wrap around” array; when queue is full,

(65)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

• How to implement?

• enqueue(item), dequeue(), size()

tail head A B tail head A B C tail head B C enque ue (C ) de que ue ()

head points to front of queue; tail points to next empty space (where next

item will be added)

head and tail “wrap around” array; when queue is full,

(66)

QueueArray

• Perhaps the most interesting implementation, so letʼs look at an example…

• How to implement?

• enqueue(item), dequeue(), size()

tail head A B tail head A B C tail head B C enque ue (C ) de que ue ()

head points to front of queue; tail points to next empty space (where next

item will be added)

head and tail “wrap around” array; when queue is full,

head == tail

After wrap around, head > tail in some

(67)
(68)
(69)

public class QueueArray<E> {

protected Object[] data; // Must use object because...

protected int head; protected int count;

(70)

public class QueueArray<E> {

protected Object[] data; // Must use object because...

protected int head; protected int count;

public QueueArray(int size) {

data = new Object[size]; // ... can’t say “new E[size]”

(71)

public class QueueArray<E> {

protected Object[] data; // Must use object because...

protected int head; protected int count;

public QueueArray(int size) {

data = new Object[size]; // ... can’t say “new E[size]”

}

public void enqueue(E item) {

Assert.pre(count < data.length, ”The queue is full.”); int tail = (head + count) % data.length;

data[tail] = item; count++;

(72)

public class QueueArray<E> {

protected Object[] data; // Must use object because...

protected int head; protected int count;

public QueueArray(int size) {

data = new Object[size]; // ... can’t say “new E[size]”

}

public void enqueue(E item) {

Assert.pre(count < data.length, ”The queue is full.”); int tail = (head + count) % data.length;

data[tail] = item; count++;

}

public E dequeue() {

assert (count > 0) :"The queue is empty."; E value = (E)data[head];

data[head] = null;

head = (head + 1) % data.length; count--;

return value; }

(73)

public class QueueArray<E> {

protected Object[] data; // Must use object because...

protected int head; protected int count;

public QueueArray(int size) {

data = new Object[size]; // ... can’t say “new E[size]”

}

public void enqueue(E item) {

assert (count < data.length) : ”The queue is full."; int tail = (head + count) % data.length;

data[tail] = item; count++;

}

public E dequeue() {

assert (count > 0) :"The queue is empty."; E value = (E)data[head];

data[head] = null;

head = (head + 1) % data.length; count--;

return value; }

public boolean empty() { return count>0;

} }

(74)

QueueArray-style QueueVector?

• Why not use this same design with a Vector as our building block? Several decisions to make:

(75)

QueueArray-style QueueVector?

• Why not use this same design with a Vector as our building block? Several decisions to make:

• How do we interpret the respective meanings of vec.elementCount, q.head, and q.count?

• How do we “grow” our Vector when our start/end are not at index 0 and vec.size()-1?

(76)

QueueArray-style QueueVector?

• Why not use this same design with a Vector as our building block? Several decisions to make:

• How do we interpret the respective meanings of vec.elementCount, q.head, and q.count?

• How do we “grow” our Vector when our start/end are not at index 0 and vec.size()-1?

• These are all things that we can overcome, but we can’t simply use a Vector as a “black box”

(77)

QueueArray-style QueueVector?

• Why not use this same design with a Vector as our building block? Several decisions to make:

• How do we interpret the respective meanings of vec.elementCount, q.head, and q.count?

• How do we “grow” our Vector when our start/end are not at index 0 and vec.size()-1?

• These are all things that we can overcome, but we can’t simply use a Vector as a “black box”

• Note: structure5 takes the “black box” approach; intentionally demonstrates tradeoff of specialization

(78)

Takeaways

•Queues, like stacks, limit our access to specific locations of our data structure

• However, this mimics common access patterns

•We can design a data structure that takes advantage of these limitations to optimize perf

•By utilizing these data structures, we can simplify/influence our algorithm design

•Enqueue/dequeue and push/pop are common terms, so be comfortable using them

References

Related documents

Accuracy analysis of the Mahalanobis distance (MD) classification, and with majority filter (MDF) for slide and nonslide areas, of the segment Sample 2, using magnitude, phase,

This paper presents a novel real-time planning algorithm, chance con- strained rapidly-exploring random trees (CC-RRT), which uses chance constraints to guarantee

Abiotic (drought, heat, and cold stress) and biotic (pod borers – Helicoverpa armigera and Spodoptera exigua, aphids – Aphis crac- civora, leaf miner – Liriomyza cicerina, and

Class participation: Throughout the course I will assign short articles from the business press (e.g., The Wall Street Journal, Business Week), including some from your packet. I

The latest report (2013) shows a signifi cant reduction in gas oil consumption used for heating the main school block, compared to before the EPC started (these fi gures are used

Kao izravan odgovor na industrijski razvoj, nastaju muzeji poput pariškog Nacionalnog muzeja za umjetnost i obrt, londonskog South Kensington muzeja posvećenog industrijskim obrtima

Our data suggest that ICT1 is a versatile ribosome rescue factor, which is also involved in the translation termination at non- standard stop codons AGG and AGA in mammalian

At a Glance Compared to Q4 2012 • Average attack bandwidth up 718 percent from 5.9 Gbps to 48.25 Gbps • Average attack duration increases 7.14 percent from 32.2 hours to 34.5