Skip to content

Commit a0e9034

Browse files
committed
New dfs implementation
1 parent f5645bb commit a0e9034

File tree

1 file changed

+34
-109
lines changed

1 file changed

+34
-109
lines changed

src/graphs/searching/dfs.js

Lines changed: 34 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,54 @@
1-
'use strict';
2-
3-
/* * * * * * * * * * * * * * * * * *
4-
5-
Sample graph
6-
7-
var graph = [[1,0,1,0,0,0],
8-
[0,1,0,1,0,0],
9-
[1,0,1,0,1,0],
10-
[0,1,0,1,1,0],
11-
[0,0,1,1,1,1],
12-
[0,0,0,0,1,1]];
13-
* * * * * * * * * * * * * * * * * */
1+
/**
2+
* Depth-First Search graph searching algorithm.
3+
* Finds out whether there's a path between
4+
* two nodes - start node and a target.
5+
*/
146

157
(function (exports) {
16-
/**
17-
* Depth-first search algorithm for matrix representation of graph.
18-
* The algorithm finds whether there's a path between two given nodes.
19-
*/
20-
var depthFirstSearch = (function () {
8+
'use strict';
219

22-
var visited = [],
23-
target,
24-
graph;
10+
var dfs = (function () {
2511

2612
/**
27-
* Returns whether the destination could be reached
28-
* from given node
29-
*
30-
* @private
31-
* @param {number} current Current node
32-
* @returns {boolean} True/false depending whether
33-
* the destination can be reached from the current node
13+
* Implements an iterative DFS.
14+
* Complexity O(|V|^2), since it uses adjust matrix.
3415
*/
35-
function dfs(current) {
36-
if (visited[current] ||
37-
current[0] < 0 || current[1] < 0 ||
38-
current[0] >= graph.length || current[1] >= graph[0].length ||
39-
!graph[current[0]][current[1]]) {
40-
return false;
41-
}
42-
if (current[0] === target[0] &&
43-
current[1] === target[1]) {
44-
return true;
45-
}
16+
function hasPath(graph, current, goal) {
17+
var stack = [],
18+
visited = [],
19+
node;
20+
stack.push(current);
4621
visited[current] = true;
47-
return dfs([current[0] + 1, current[1]]) ||
48-
dfs([current[0] - 1, current[1]]) ||
49-
dfs([current[0], current[1] + 1]) ||
50-
dfs([current[0], current[1] - 1]);
51-
}
52-
53-
/**
54-
* Initializes the algorithm
55-
*
56-
* @private
57-
* @param {array} inputGraph The input matrix of the graph
58-
* @param {number} destination The destination
59-
*/
60-
function init(inputGraph, destination) {
61-
graph = inputGraph;
62-
target = destination;
63-
visited = {};
64-
}
65-
66-
/**
67-
* Validates the params
68-
*
69-
* @param {array} graph A matrix representation of the graph
70-
* @param {array} source The source node
71-
* @param {array} destination The destination node
72-
*/
73-
function validateParams(graph, source, destination) {
74-
if (!graph) {
75-
throw new Error('The graph should be represented as a matrix');
76-
}
77-
if (graph[0] === undefined) {
78-
throw new Error('The graph should be represented as ' +
79-
'a matrix, with size at least 1x1');
80-
}
81-
var width = graph[0].length;
82-
for (var i = 1; i < graph.length; i += 1) {
83-
if (graph[i].length !== width) {
84-
throw new Error('The graph should be represented as a matrix');
22+
while (stack.length) {
23+
node = stack.pop();
24+
if (node === goal) {
25+
return true;
8526
}
86-
}
87-
source.concat(destination).filter(function (c, i) {
88-
if (c < 0) {
89-
throw new Error('The source and destination coordinates ' +
90-
'should be above zero');
91-
}
92-
if (i % 2 === 0) {
93-
if (c >= graph.length) {
94-
throw new Error('The source and destination coordinates ' +
95-
'should not be above graph\'s size');
96-
}
97-
} else {
98-
if (c >= graph[0].length) {
99-
throw new Error('The source and destination coordinates ' +
100-
'should not be above graph\'s size');
27+
for (var i = 0; i < graph[node].length; i += 1) {
28+
if (graph[node][i] && !visited[i]) {
29+
stack.push(i);
30+
visited[i] = true;
10131
}
10232
}
103-
});
104-
return true;
33+
}
34+
return false;
10535
}
10636

10737
/**
108-
* Finds whether there's a path between a given start node
109-
* to given destination
38+
* Returns whether there's a path between two nodes
39+
* in a graph represented with adjust matrix.
11040
*
11141
* @public
112-
* @param {array} graph A matrix representation of the graph
113-
* @param {number} source The source node
114-
* @param {number} destination The destination node
115-
* @returns {boolean} true/false depending
116-
* whether there's a path between the nodes
42+
* @param {array} graph Adjust matrix representation of a graph
43+
* @param {number} start A start node
44+
* @param {number} goal The target node
45+
* @return {boolean} Returns whether there's a path between start and goal
11746
*/
118-
return function (graph, source, destination) {
119-
validateParams(graph, source, destination);
120-
init(graph, destination);
121-
return dfs(source);
47+
return function (graph, start, goal) {
48+
return hasPath(graph, start, goal);
12249
};
123-
124-
12550
}());
12651

127-
exports.depthFirstSearch = depthFirstSearch;
52+
exports.dfs = dfs;
12853

129-
}(typeof exports === 'undefined' ? window : exports));
54+
}(typeof exports === 'undefined' ? window : exports));

0 commit comments

Comments
 (0)