guava/src/com/google/common/graph/Traverser.java
public static <N> Traverser<N> forTree(SuccessorsFunction<N> tree) {
    checkNotNull(tree);
    if (tree instanceof BaseGraph) {
      checkArgument(((BaseGraph<?>) tree).isDirected(), "Undirected graphs can never be trees.");
    }
    if (tree instanceof Network) {
      checkArgument(((Network<?, ?>) tree).isDirected(), "Undirected networks can never be trees.");
    }
    return new TreeTraverser<>(tree);
  }
public static <N> Traverser<N> forTree(SuccessorsFunction<N> tree) {
    checkNotNull(tree);
    if (tree instanceof BaseGraph) {
      checkArgument(((BaseGraph<?>) tree).isDirected(), "Undirected graphs can never be trees.");
    }
    if (tree instanceof Network) {
      checkArgument(((Network<?, ?>) tree).isDirected(), "Undirected networks can never be trees.");
    }
    return new TreeTraverser<>(tree);
  }
Creates a new traverser for a directed acyclic graph that has at most one path from the start
node(s) to any node reachable from the start node(s), and has no paths from any start node to
any other start node, such as a tree or forest.

<p>{@code forTree()} is especially useful (versus {@code forGraph()}) in cases where the data
structure being traversed is, in addition to being a tree/forest, also defined <a
href="https://github.com/google/guava/wiki/GraphsExplained#non-recursiveness">recursively</a>.
This is because the {@code forTree()}-based implementations don't keep track of visited nodes,
and therefore don't need to call `equals()` or `hashCode()` on the node objects; this saves
both time and space versus traversing the same graph using {@code forGraph()}.

<p>Providing a graph to be traversed for which there is more than one path from the start
node(s) to any node may lead to:

<ul>
<li>Traversal not terminating (if the graph has cycles)
<li>Nodes being visited multiple times (if multiple paths exist from any start node to any
node reachable from any start node)
</ul>

<p><b>Performance notes</b>

<ul>
<li>Traversals require <i>O(n)</i> time (where <i>n</i> is the number of nodes reachable from
the start node).
<li>While traversing, the traverser will use <i>O(H)</i> space (where <i>H</i> is the number
of nodes that have been seen but not yet visited, that is, the "horizon").
</ul>

<p><b>Examples</b> (all edges are directed facing downwards)

<p>The graph below would be valid input with start nodes of {@code a, f, c}. However, if {@code
b} were <i>also</i> a start node, then there would be multiple paths to reach {@code e} and
{@code h}.

<pre>{@code
a     b      c
/ \   / \     |
/   \ /   \    |
d     e     f   g
|
|
h
}</pre>

<p>.

<p>The graph below would be a valid input with start nodes of {@code a, f}. However, if {@code
b} were a start node, there would be multiple paths to {@code f}.

<pre>{@code
a     b
/ \   / \
/   \ /   \
c     d     e
\   /
\ /
f
}</pre>

<p><b>Note on binary trees</b>

<p>This method can be used to traverse over a binary tree. Given methods {@code
leftChild(node)} and {@code rightChild(node)}, this method can be called as

<pre>{@code
Traverser.forTree(node -> ImmutableList.of(leftChild(node), rightChild(node)));
}</pre>

@param tree {@link SuccessorsFunction} representing a directed acyclic graph that has at most
one path between any two nodes