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