|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
public interface Graph<T>
This Interface specifies a basic directed graph data structure in "adjacency list" representation. It supports operations such as adding nodes and arcs/edges, finding nodes and the neighbors of a node, etc. It does not support deletion of nodes, node or edge annotation, or edge weights.
Implementation of this type rely on the input objects' versions of
Object.equals(Object) and
Object.hashCode() to establish identity and comparison. Such implementations
MUST NOT rely on any natural ordering among the nodes.
| Method Summary | |
|---|---|
void |
addEdge(T from,
T to)
Insert a directed edge between two nodes. |
void |
addNode(T node)
Insert a new node into this graph. |
boolean |
containsEdge(T from,
T to)
Test for the presence of a directed edge between two nodes. |
boolean |
containsNode(T node)
Returns true iff the argument specifies a node in the graph. |
int |
edgeCount()
Return a count of the total number of unique, directed edges in the graph. |
boolean |
equals(Object o)
Every concrete class for the Graph interface MUST implement the equals()
method, as specified by Object.equals(Object). |
Iterator<SearchState<T>> |
getBFSIterator(T node)
Produce an iterator for a breadth-first search of the graph, starting at a fixed node. |
Iterator<SearchState<T>> |
getDFSIterator(T node)
Produce an iterator for a depth-first search of the graph, starting at a fixed node. |
T |
getNodeByID(int nodeID)
Return the node corresponding to the specified ID. |
int |
getNodeID(T node)
Return a unique numeric ID code on the range [0,V-1] for the specified node. |
int |
hashCode()
Every concrete instantiation of the Graph interface MUST implement
the hashCode method, as specified by Object.hashCode(). |
int |
neighborCount(T node)
Get the number of neighbors of a target node. |
Set<T> |
neighborSet(T node)
Returns an immutable set view of all of the neighbors of a fixed node in the graph. |
Set<T> |
nodeSet()
Returns an immutable set view of all of the nodes in the graph. |
int |
size()
Returns the number of nodes in this graph. |
| Method Detail |
|---|
void addNode(T node)
null argument generates a
NullPointerException. If the node is already present in the graph, this
method silently returns with no effect. (Specifically it MUST NOT
either generate an exception or add a second copy of the node to the graph.)
This method MUST run in amortized O(1) time.
node - Node to add to graph.
NullPointerException - iff node==nullboolean containsNode(T node)
true iff the argument specifies a node in the graph.
This method MUST run in O(1) time.
node - Node to test
Set<T> nodeSet()
Set object gives access to all of the elements in the underlying graph
as if they were members of the set itself, though it MUST NOT create new copies
of the nodes. It MUST support the full Set interface, including a correct
Iterator method. The returned Set MUST be immutable. Specifically,
the Set.add(Object), Set.remove(Object), etc. methods that would
normally modify the state of the object MUST all throw UnsupportedOperationException
if called. Further, the Iterator that the Set returns MUST also
be immutable, as must any other derived objects.
Note that the Set object returned by this is free to, itself,
represent an arbitrary order on nodes. That is, it is free to iterate over
the nodes in any order it wishes, so long as it correctly enumerates the
entire node set.
If the graph is currently empty, this still returns a Set, but that set
is empty (nodeSet().size()==0).
This method MUST run in O(1) time. The returned Set view MUST
use O(1) space and implement
Set.contains(Object) in O(1) time. The Set.iterator() call
MUST run in O(1) time. The returned Iterator object MUST require
only O(1) space, MUST return
each element in O(1) time, and MUST be capable of iterating over all n
nodes of the graph in Theta(n) time.
int size()
edgeCount()), diameter, maximum indegree/outdegree,
etc.
Because multiple node additions are ignored (see addNode(Object), this
is also unaffected by re-addition of a node.
This method MUST return in O(1) time.
void addEdge(T from,
T to)
throws GraphStructureException
GraphStructureException to
indicate a violation of this assumption. This method does allow
self-edges (i.e., an edge from node X to node X).
Because this graph supports directed edges,
addEdge(X,Y) is not the same as addEdge(Y,X), when
!X.equals(Y).
An already-existing edge may be re-added, but this is silently ignored and does not change the data structure at all. (In particular, it does not change the total edge count.)
This method MUST run in amortized O(1) time and require only amortized O(1) space.
from - Parent/orgin of the edgeto - Child/destination of the edge
GraphStructureException - if either of from or to
are not present in the graph.
boolean containsEdge(T from,
T to)
true iff both from and to are nodes in the
graph and they are connected by a directed edge that originates at from
and terminates at to. (That is,
containsEdge(X,Y)==true iff addEdge(X,Y) was
successfully executed at some time in the past.
Note that this simply returns false if either from or
to does not exist in this graph. It MUST NOT fail or throw an
exception in this case.
This method MUST run in O(1) time and require O(1) new space allocation.
from - Parent node to testto - Child node to test
true iff nodes are connectedint edgeCount()
Because multiple node additions are ignored (see addEdge(Object, Object), this
is also unaffected by re-addition of an edge.
This method MUST run in O(1) time and require 0 new space allocation.
Set<T> neighborSet(T node)
throws GraphStructureException
addEdge(X,Y) has successfully been executed some time in the
past, then neighborSet(X).contains(Y)==true (otherwise, it is false).
The returned
Set object gives access to all of the neighbor nodes of the query
as if they were members of the set itself, though it MUST NOT create new copies
of the nodes. It MUST support the full Set interface, including a correct
Iterator method. The returned Set MUST be immutable. Specifically,
the Set.add(Object), Set.remove(Object), etc. methods that would
normally modify the state of the object MUST all throw
UnsupportedOperationException if called. Further, the Iterator
that the Set returns MUST also
be immutable, as must any other derived objects.
If node is not a member of the graph (i.e., containsNode(Object)
is false), then this throws a GraphStructureException to indicate
a malformed query.
Note that the Set returned by this method is free to represent the
neighbors of a node in any order it wishes.
If the queried node exists, but has no neighbors, this still returns a
Set, but that Set is empty (i.e., neighborSet(X).size()==0).
This method MUST run in O(1) time. The returned Set view MUST
use O(1) space and implement
Set.contains(Object) in O(1) time. The Set.iterator() call
MUST run in O(1) time. The returned Iterator object MUST require
only O(1) space, MUST return
each element in O(1) time, and MUST be capable of iterating over all n
neighbor nodes in Theta(n) time.
node - Node whose neighbors should be queried.
node
GraphStructureException - if node doesn't exist in this graph
int neighborCount(T node)
throws GraphStructureException
If node is not a member of the graph (i.e., containsNode(Object)
is false), then this throws a GraphStructureException to indicate
a malformed query.
This method MUST run in O(1) time and require 0 additional space.
node - Target node to examine
node
GraphStructureException - if node doesn't exist in this graph
Iterator<SearchState<T>> getDFSIterator(T node)
throws GraphStructureException
Iterator.next() MUST run in amortized
O(1) time. The iterator MAY use more than O(1) space to store
its state, though it MUST NOT make a complete copy of the graph.
In particular, it MAY use space up to O(size()) to store
state, but it MUST NOT use as much as O(edgeCount().
The getDFSIterator(Object) method MUST return in O(1) time.
Specifically, it MUST NOT copy or make explicit reference to all nodes or
all edges of the graph.
node - Starting point for the traversal.
Iterator for a depth-first search of the graph. Note that
the returned iterator itself generates SearchState objects. These
objects allow clients to retrieve not only the node of the current point of
the iteration, but also the path by which the current node was generated
in the search and the depth of the node in the search.
GraphStructureException - If the starting node is not a legitimate
node of the graph.
Iterator<SearchState<T>> getBFSIterator(T node)
throws GraphStructureException
Iterator.next() MUST run in amortized
O(1) time. The iterator MAY use more than O(1) space to store
its state, though it MUST NOT make a complete copy of the graph.
In particular, it MAY use space up to O(size()) to store
state, but it MUST NOT use as much as O(edgeCount().
The getBFSIterator(Object) method MUST return in O(1) time.
Specifically, it MUST NOT copy or make explicit reference to all nodes or
all edges of the graph.
node - Starting point for the traversal.
Iterator for a breadth-first search of the graph. Note that
the returned iterator itself generates SearchState objects. These
objects allow clients to retrieve not only the node of the current point of
the iteration, but also the path by which the current node was generated
in the search and the depth of the node in the search. (For a
breadth-first search in an unweighted graph, this is guaranteed to yield
the shortest path to a node.)
GraphStructureException - If the starting node is not a legitimate
node of the graph.boolean equals(Object o)
equals()
method, as specified by Object.equals(Object). For graph objects,
equality is defined to be:
Two graphs are equal iff they have the same node sets and same edge sets. Specifically:
g1 must be present in g2, according to the
Object.equals(Object) method for those nodes (and vice-versa).
g1 must be present in g2 (and
vice-versa). That is,
if this.containsNode(X) && this.containsNode(Y) && this.containsEdge(X,Y)
then it must be the case that
o.containsNode(X) && o.containsNode(Y) && o.containsEdge(X,Y)
This method MUST NOT generate any exceptions. If one of the two graphs does not
contain some node/edge that exists in the other, then this MUST return false.
This MUST also return false, rather than throwing an exception,
when o is not a Graph object.
This method MUST run in O(V+E) time, where V is the number of nodes (vertices) in either graph and E is the number of edges.
equals in class Objecto - Object to compare to.
true iff o is a Graph and
o represents the same graph as this object.int hashCode()
Graph interface MUST implement
the hashCode method, as specified by Object.hashCode().
For graph objects, to ensure consistency with equals(Object), the hash code
is defined to be:
hc=0
for g in nodes {
hc=hc+g.hashCode
}
for e in edges {
hc=hc+((e.parent.hashCode)^2)*e.child.hashCode
}
return hc
where x^2 should be read as "x squared". (Hint: be sure to
use integer arithmatic to do the squaring, rather than Math.pow(double, double),
which will cast to double.)
This method MUST NOT generate any exceptions.
This method MUST run in O(V+E) time, where V is the number of nodes (vertices) in the graph and E is the number of edges.
hashCode in class Object
int getNodeID(T node)
throws GraphStructureException
[0,V-1] for the specified node. This
function maps every node in the graph to a unique, small, non-negative integer.
Such integers can be used, for example, to construct an adjacency matrix representation
of the graph.
The returned code MUST be non-negative and MUST be <size() (i.e.,
the code must be on the range [0,V-1] for a graph with V
nodes/vertices).
The nodes MAY, however, be ordered in any way, subject to that constraint and the
following constraint:
The returned ID code for a node MUST be stable -- calling getNodeID(X),
for some node X, MUST return the same ID code, regardless of when it
is called, how many times it has been called, whether other nodes have been inserted
into the graph in the interim, etc. The code MAY, however, be selected lazily or
on node insertion.
If the node is not an element of the graph, this generates a
GraphStructureException to indicate the error.
This method MUST run in O(1) time and require at most O(1) space allocation.
node - Graph node for which to generate an ID code
GraphStructureException
T getNodeByID(int nodeID)
throws GraphStructureException
getNodeID(Object) -- it takes an ID code, and
returns the node that corresponds to it. This can be used to retrieve
a node, when all you have is a node ID (e.g., for mapping from an
adjacency matrix representation of the graph back into an adjacency list).
If the nodeID does not correspond to any node, this generates
a GraphStructureException to indicate the error.
This method MUST run in O(1) time and require at most O(1) space allocation.
nodeID - Graph node ID for which to retrieve the node.
nodeID.
GraphStructureException - If nodeID does not exist
in the graph.
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||