43 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			43 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var _ = require("../lodash");
 | |
| 
 | |
| module.exports = dfs;
 | |
| 
 | |
| /*
 | |
|  * A helper that preforms a pre- or post-order traversal on the input graph
 | |
|  * and returns the nodes in the order they were visited. If the graph is
 | |
|  * undirected then this algorithm will navigate using neighbors. If the graph
 | |
|  * is directed then this algorithm will navigate using successors.
 | |
|  *
 | |
|  * Order must be one of "pre" or "post".
 | |
|  */
 | |
| function dfs(g, vs, order) {
 | |
|   if (!_.isArray(vs)) {
 | |
|     vs = [vs];
 | |
|   }
 | |
| 
 | |
|   var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g);
 | |
| 
 | |
|   var acc = [];
 | |
|   var visited = {};
 | |
|   _.each(vs, function(v) {
 | |
|     if (!g.hasNode(v)) {
 | |
|       throw new Error("Graph does not have node: " + v);
 | |
|     }
 | |
| 
 | |
|     doDfs(g, v, order === "post", visited, navigation, acc);
 | |
|   });
 | |
|   return acc;
 | |
| }
 | |
| 
 | |
| function doDfs(g, v, postorder, visited, navigation, acc) {
 | |
|   if (!_.has(visited, v)) {
 | |
|     visited[v] = true;
 | |
| 
 | |
|     if (!postorder) { acc.push(v); }
 | |
|     _.each(navigation(v), function(w) {
 | |
|       doDfs(g, w, postorder, visited, navigation, acc);
 | |
|     });
 | |
|     if (postorder) { acc.push(v); }
 | |
|   }
 | |
| }
 |