Skip to content

Commit

Permalink
preorder and postorder can take a list of roots
Browse files Browse the repository at this point in the history
  • Loading branch information
cpettitt committed Sep 24, 2014
1 parent b90f9bf commit 2a9d8ca
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 11 deletions.
20 changes: 13 additions & 7 deletions lib/alg/dfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var _ = require("lodash");
module.exports = dfs;

/*
* dfs(graph, root, order, [traversalFunction], [successorFunction])
* dfs(graph, roots, order, [traversalFunction], [successorFunction])
*
* A helper function for doing dfs traversals in pre- or post-order. The root
* node must be in the graph.
Expand All @@ -19,21 +19,27 @@ module.exports = dfs;
* that should be traversed. By default it uses the graph's "successor"
* function.
*/
function dfs(g, v, order, fn, successors) {
function dfs(g, vs, order, fn, successors) {
if (!successors) {
successors = g.successors.bind(g);
}

if (!g.hasNode(v)) {
throw new Error("Graph does not have node: " + v);
}

if (!fn) {
fn = _.constant(true);
}

if (!_.isArray(vs)) {
vs = [vs];
}

var acc = [];
doDfs(v, order, fn, successors, {}, acc);
_.each(vs, function(v) {
if (!g.hasNode(v)) {
throw new Error("Graph does not have node: " + v);
}

doDfs(v, order, fn, successors, {}, acc);
});
return acc;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/alg/postorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ var dfs = require("./dfs");

module.exports = preorder;

function preorder(g, v, fn, successors) {
return dfs(g, v, "post", fn, successors);
function preorder(g, vs, fn, successors) {
return dfs(g, vs, "post", fn, successors);
}
4 changes: 2 additions & 2 deletions lib/alg/preorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ var dfs = require("./dfs");

module.exports = preorder;

function preorder(g, v, fn, successors) {
return dfs(g, v, "pre", fn, successors);
function preorder(g, vs, fn, successors) {
return dfs(g, vs, "pre", fn, successors);
}
13 changes: 13 additions & 0 deletions test/alg/postorder-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ describe("alg.postorder", function() {
Math.min(nodes.indexOf("b"), nodes.indexOf("c")));
});

it("works for an array of roots", function() {
var g = new Digraph();
g.setEdge("a", "b");
g.setEdge("c", "d");
g.setNode("e");
g.setNode("f");

var nodes = postorder(g, ["a", "c", "e"]);
expect(_.sortBy(nodes)).to.eql(["a", "b", "c", "d", "e"]);
expect(nodes.indexOf("b")).to.be.lt(nodes.indexOf("a"));
expect(nodes.indexOf("d")).to.be.lt(nodes.indexOf("c"));
});

it("finishes early if the callback returns false", function() {
var g = new Digraph();
g.setPath(["a", "b", "c", "d"]);
Expand Down
13 changes: 13 additions & 0 deletions test/alg/preorder-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ describe("alg.preorder", function() {
nodes.indexOf("d"));
});

it("works for an array of roots", function() {
var g = new Digraph();
g.setEdge("a", "b");
g.setEdge("c", "d");
g.setNode("e");
g.setNode("f");

var nodes = preorder(g, ["a", "c", "e"]);
expect(_.sortBy(nodes)).to.eql(["a", "b", "c", "d", "e"]);
expect(nodes.indexOf("b")).to.be.gt(nodes.indexOf("a"));
expect(nodes.indexOf("d")).to.be.gt(nodes.indexOf("c"));
});

it("finishes early if the callback returns false", function() {
var g = new Digraph();
g.setPath(["a", "b", "c", "d"]);
Expand Down

0 comments on commit 2a9d8ca

Please sign in to comment.