| Index: lib/src/graph.dart
|
| diff --git a/lib/src/graph.dart b/lib/src/graph.dart
|
| index 4bb7f4b78c3daf17c132088dbe5b041fae918b64..5602d6e58b21a43a94d3d69aaa2d53d6bafee28a 100644
|
| --- a/lib/src/graph.dart
|
| +++ b/lib/src/graph.dart
|
| @@ -3,7 +3,7 @@
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| /// A library to work with graphs. It contains a couple algorithms, including
|
| -/// Tarjan's algorithm to compute strongest connected components in a graph and
|
| +/// Tarjan's algorithm to compute strongly connected components in a graph and
|
| /// Cooper et al's dominator algorithm.
|
| ///
|
| /// Portions of the code in this library was adapted from
|
| @@ -41,21 +41,35 @@ abstract class Graph<N> {
|
| }
|
|
|
| /// Returns all nodes reachable from [root] in post order.
|
| - List<N> postOrder(N root) {
|
| + Iterable<N> postOrder(N root) sync* {
|
| var seen = new Set<N>();
|
| - var result = <N>[];
|
| - helper(n) {
|
| + Iterable<N> helper(n) sync* {
|
| if (!seen.add(n)) return;
|
| - targetsOf(n).forEach(helper);
|
| - result.add(n);
|
| + for (var x in targetsOf(n)) {
|
| + yield* helper(x);
|
| + }
|
| + yield n;
|
| + }
|
| + yield* helper(root);
|
| + }
|
| +
|
| + /// Returns an iterable of all nodes reachable from [root] in preorder.
|
| + Iterable<N> preOrder(N root) sync* {
|
| + var seen = new Set<N>();
|
| + var stack = <N>[root];
|
| + while (stack.isNotEmpty) {
|
| + var next = stack.removeLast();
|
| + if (!seen.contains(next)) {
|
| + seen.add(next);
|
| + yield next;
|
| + stack.addAll(targetsOf(next));
|
| + }
|
| }
|
| - helper(root);
|
| - return result;
|
| }
|
|
|
| - /// Return a list of nodes that form a cycle containing the given node. If the
|
| - /// node is not part of a cycle in this graph, then a list containing only the
|
| - /// node itself will be returned.
|
| + /// Returns a list of nodes that form a cycle containing the given node. If
|
| + /// the node is not part of a cycle in this graph, then a list containing only
|
| + /// the node itself will be returned.
|
| List<N> findCycleContaining(N node) {
|
| assert(node != null);
|
| _SccFinder<N> finder = new _SccFinder<N>(this);
|
| @@ -273,7 +287,7 @@ class _DominatorFinder<N> {
|
| immediateDominators[root] = root;
|
| bool changed = true;
|
| int i = 0;
|
| - var nodesInPostOrder = _graph.postOrder(root);
|
| + var nodesInPostOrder = _graph.postOrder(root).toList();
|
| for (var n in nodesInPostOrder) {
|
| postOrderId[n] = i++;
|
| }
|
|
|