Class Traverser<T>
- Type Parameters:
T
- Node parameter type
-
Field Summary
-
Method Summary
Modifier and TypeMethodDescriptionbreadthFirst
(T startNode) Returns an unmodifiableIterable
over the nodes reachable fromstartNode
, in the order of a breadth-first traversal.depthFirstPostOrder
(T startNode) Returns an unmodifiableIterable
over the nodes reachable fromstartNode
, in the order of a depth-first post-order traversal.depthFirstPreOrder
(T startNode) Returns an unmodifiableIterable
over the nodes reachable fromstartNode
, in the order of a depth-first pre-order traversal.static <T> Traverser<T>
Creates a new traverser for the given generalgraph
.static <T> Traverser<T>
Creates a new traverser for a directed acyclic graph that has at most one path from the start node to any node reachable from the start node, such as a tree.
-
Field Details
-
FILES
-
-
Method Details
-
forTree
Creates a new traverser for a directed acyclic graph that has at most one path from the start node to any node reachable from the start node, such as a tree.Providing graphs that don't conform to the above description may lead to:
- Traversal not terminating (if the graph has cycles)
- Nodes being visited multiple times (if multiple paths exist from the start node to any node reachable from it)
#forGraph(SuccessorsFunction)
instead.Performance notes
- Traversals require O(n) time (where n is the number of nodes reachable from the start node).
- While traversing, the traverser will use O(H) space (where H is the number of nodes that have been seen but not yet visited, that is, the "horizon").
Examples
This is a valid input graph (all edges are directed facing downwards):
a b c / \ / \ | / \ / \ | d e f g | | h
This is not a valid input graph (all edges are directed facing downwards):
a b / \ / \ / \ / \ c d e \ / \ / f
because there are two paths from
b
tof
(b->d->f
andb->e->f
).Note on binary trees
This method can be used to traverse over a binary tree. Given methods
leftChild(node)
andrightChild(node)
, this method can be called asTraverser.forTree(node -> ImmutableList.of(leftChild(node), rightChild(node)));
- Type Parameters:
T
-- Parameters:
tree
-SuccessorsFunction
representing a directed acyclic graph that has at most one path between any two nodes- Returns:
-
forGraph
Creates a new traverser for the given generalgraph
.If
graph
is known to be tree-shaped, consider using#forTree(SuccessorsFunction)
instead.Performance notes
- Traversals require O(n) time (where n is the number of nodes reachable from
the start node), assuming that the node objects have O(1)
equals()
andhashCode()
implementations. - While traversing, the traverser will use O(n) space (where n is the number of nodes that have thus far been visited), plus O(H) space (where H is the number of nodes that have been seen but not yet visited, that is, the "horizon").
- Type Parameters:
T
-- Parameters:
graph
-SuccessorsFunction
representing a general graph that may have cycles.- Returns:
- Traversals require O(n) time (where n is the number of nodes reachable from
the start node), assuming that the node objects have O(1)
-
breadthFirst
Returns an unmodifiableIterable
over the nodes reachable fromstartNode
, in the order of a breadth-first traversal. That is, all the nodes of depth 0 are returned, then depth 1, then 2, and so on.Example: The following graph with
startNode
a
would return nodes in the orderabcdef
(assuming successors are returned in alphabetical order).b ---- a ---- d | | | | e ---- c ---- f
The behavior of this method is undefined if the nodes, or the topology of the graph, change while iteration is in progress.
The returned
Iterable
can be iterated over multiple times. Every iterator will compute its next element on the fly. It is thus possible to limit the traversal to a certain number of nodes as follows:Iterables.limit(Traverser.forGraph(graph).breadthFirst(node), maxNumberOfNodes);
See Wikipedia for more info.
- Parameters:
startNode
-- Returns:
- Throws:
IllegalArgumentException
- ifstartNode
is not an element of the graph
-
depthFirstPreOrder
Returns an unmodifiableIterable
over the nodes reachable fromstartNode
, in the order of a depth-first pre-order traversal. "Pre-order" implies that nodes appear in theIterable
in the order in which they are first visited.Example: The following graph with
startNode
a
would return nodes in the orderabecfd
(assuming successors are returned in alphabetical order).b ---- a ---- d | | | | e ---- c ---- f
The behavior of this method is undefined if the nodes, or the topology of the graph, change while iteration is in progress.
The returned
Iterable
can be iterated over multiple times. Every iterator will compute its next element on the fly. It is thus possible to limit the traversal to a certain number of nodes as follows:Iterables.limit( Traverser.forGraph(graph).depthFirstPreOrder(node), maxNumberOfNodes);
See Wikipedia for more info.
- Parameters:
startNode
-- Returns:
- Throws:
IllegalArgumentException
- ifstartNode
is not an element of the graph
-
depthFirstPostOrder
Returns an unmodifiableIterable
over the nodes reachable fromstartNode
, in the order of a depth-first post-order traversal. "Post-order" implies that nodes appear in theIterable
in the order in which they are visited for the last time.Example: The following graph with
startNode
a
would return nodes in the orderfcebda
(assuming successors are returned in alphabetical order).b ---- a ---- d | | | | e ---- c ---- f
The behavior of this method is undefined if the nodes, or the topology of the graph, change while iteration is in progress.
The returned
Iterable
can be iterated over multiple times. Every iterator will compute its next element on the fly. It is thus possible to limit the traversal to a certain number of nodes as follows:Iterables.limit( Traverser.forGraph(graph).depthFirstPostOrder(node), maxNumberOfNodes);
See Wikipedia for more info.
- Parameters:
startNode
-- Returns:
- Throws:
IllegalArgumentException
- ifstartNode
is not an element of the graph
-