Computer Science 15-111 (Sections A & B), Spring 2007
Class Notes: 28-Mar-2007
Logistics:
1.
Reading (same as last class):
a.
Java by Dissection, Sections 12.5 –
12.6 (Stacks) and 12.7 (Queues)
b.
Javanotes, Section 9.3 (all of it,
including Queues)
2.
Reminder: Study StackByInheritance.java
a.
know how to create your own
interfaces, exceptions, and parameterized classes.
Topics:
1. Queues
a. Word History (from http://dictionary.reference.com/browse/queue):
“When the
British stand in queues (as they have been doing at least since 1837, when this
meaning of the word is first recorded in English), they may not realize they
form a tail. The French word queue from which the English word is borrowed is a
descendant of Latin cōda, meaning "tail." French queue appeared
in 1748 in English, referring to a plait of hair hanging down the back of the
neck. By 1802 wearing a queue was a regulation in the British army, but by the
mid-19th century queues had disappeared along with cocked hats. Latin cōda
is also the source of Italian coda, which was adopted into English as a musical
term (like so many other English musical terms that come from Italian). A coda
is thus literally the "tail end" of a movement or composition.”
Churchill is said to have coined
Queuetopia (1950), to describe Britain under Labour or Socialist rule.” My wife, having just heard this quote, said
it was “Queuet”.
b. FIFO == “First In First out”
c. Operations:
i.
Enqueue
(or “push”): Add to the back of the queue
ii.
Dequeue
(or “pop”): Remove from the front of the
stack
iii.
Others (Peek, IsEmpty, …)
d. Typical Implementation as Linked
List (singly or doubly, perhaps circularly)
i.
Q: Why is it reasonable for Java to implement a
Stack as a Vector (which it does), but it is unreasonable to implement a Queue
that way?
ii.
Add
to back of singly-linked list and Remove from front (why?)
iii.
Circularly-linked
list may be a good choice here (why?)
e. Java Queue: java.util.Queue
i.
This
is an interface, not a class (like
java.util.Stack)
ii.
The
naming is peculiar:
1. “peek” is there, but so is the
nearly-identical method “element”
2. “enqueue” à
“offer”
3. “dequeue” à
“remove”, but there is the nearly-identical method “poll”
iii.
The
description is peculiar:
1. “Queues typically, but do not
necessarily, order elements in a FIFO (first-in-first-out) manner. Among the
exceptions are priority queues, which order elements according to a supplied comparator,
or the elements' natural ordering, and LIFO queues (or stacks) which order the
elements LIFO (last-in-first-out).”
2. This is a broader use of the word
“queue” than we shall use.
a. Queue == FIFO
b. Stack == LIFO
c. Priority Queue comes later and is
neither FIFO nor LIFO
iv.
The
implementing class is peculiar:
1. java.util.LinkedList
implements Queue
a. So name is perhaps misleading
b. Also: this is not synchronized, but java.util.Stack
is!
2. You may wish to do this:
@SuppressWarnings(value={"unchecked"})
class Queue extends LinkedList {
public void enqueue(Object obj) {
add(obj); }
public Object dequeue() { return
remove(); }
public boolean isEmpty() { return
(size() == 0); }
}
f.
Q: What are the tradeoffs (including Big-Oh
runtimes of enqueue and dequeue operations) in backing a Queue with:
i.
Singly-Linked
List
ii.
Doubly-Linked
List
iii.
Circularly-Linked
(singly-linked or doubly-linked) List
iv.
ArrayList
v.
Two
Stacks (think about this!)
2. Queues versus Stacks
a. Typical use in programs
i.
Stack: the call stack
ii.
Queue: the event queue
b. Typical use in search
i.
Stack: depth-first search (DFS)
ii.
Queue:
breadth-first search (BFS)
3. DFS versus BFS
//
DfsBfs.java
//
Demonstrates depth-first search and breadth-first search
//
using a stack or a queue (respectively).
//
Note that DFS is usually implemented recursively, rather
//
than using an explicit stack, and further that the recursive
//
calls at each level typically occur before fully expanding that level,
// unlike
here, so the order in which nodes are "visited" is different here.
//
Standard disclaimer: As usual with
sample code designed (often in
//
class!) to demonstrate specific issues, the style may not be perfect
//
(it is especially lacking comments and some top-down design),
//
and there may even be a bug or two lurking in the code!
import
static java.lang.System.out;
import
java.util.*;
@SuppressWarnings(value={"unchecked"})
class
Queue extends LinkedList {
public void enqueue(Object obj) {
add(obj); }
public Object dequeue() { return
remove(); }
public boolean isEmpty() { return (size()
== 0); }
}
@SuppressWarnings(value={"unchecked"})
abstract
public class DfsBfs {
protected int islands = 20;
protected boolean[][] hasBridge = new
boolean[islands][islands];
protected boolean[] visited;
public void addBridge(int island1, int
island2) {
hasBridge[island1][island2] =
hasBridge[island2][island1] = true;
}
public DfsBfs() {
addBridge(0,1); addBridge(0,2); addBridge(0,3);
addBridge(1,3); addBridge(1,4);
addBridge(2,5);
addBridge(4,6);
}
abstract public void clearList();
abstract public void addToList(Integer
i);
abstract public boolean listIsEmpty();
abstract public Integer removeFromList();
abstract public String listToString();
public boolean isConnected(int island1,
int island2) {
out.printf("\n%s.isConnected(%d,%d):\n",getClass().getName(),island1,island2);
clearList();
visited = new boolean[islands];
addToList(island1);
out.printf("Starting with %d:
%s\n",island1,listToString());
visited[island1] = true;
while (!listIsEmpty()) {
int island =
removeFromList();
out.printf("Removing
%d: %s\n",island,listToString());
if (island == island2)
return true;
for (int i=0; i<islands;
i++)
if (hasBridge[island][i]
&& (!visited[i])) {
addToList(i);
visited[i] =
true;
out.printf("Adding
%d->%d: %s\n",
island,i,listToString());
}
}
return false;
}
public static void main(String[] args) {
DfsBfs dfs = new DepthFirstSearch();
DfsBfs bfs = new
BreadthFirstSearch();
out.println(dfs.isConnected(0,6));
out.println(bfs.isConnected(0,6));
}
}
@SuppressWarnings(value={"unchecked"})
class
DepthFirstSearch extends DfsBfs {
private Stack stack;
public void clearList() { stack = new
Stack(); }
public void addToList(Integer i) {
stack.push(i); }
public boolean listIsEmpty() { return
stack.empty(); }
public Integer removeFromList() { return
(Integer)stack.pop(); }
public String listToString() { return
stack.toString(); }
}
@SuppressWarnings(value={"unchecked"})
class
BreadthFirstSearch extends DfsBfs {
private Queue queue;
public void clearList() { queue = new
Queue(); }
public void addToList(Integer i) {
queue.enqueue(i); }
public boolean listIsEmpty() { return
queue.isEmpty(); }
public Integer removeFromList() { return
(Integer)queue.dequeue(); }
public String listToString() { return
queue.toString(); }
}