Skip to content

Commit 0b2e521

Browse files
authored
Merge pull request thuva4#262 from maaz93/dfs-in-js
Depth First Search in JavaScript
2 parents e4ef2df + b622c5f commit 0b2e521

File tree

2 files changed

+131
-1
lines changed

2 files changed

+131
-1
lines changed

DepthFirstSearch/JavaScript/DFS.js

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Fully runnable code with tests at https://codepen.io/sniper6/pen/QqzYEa
2+
3+
const DFS = (graph, source, target = -1) => {
4+
// Some error handling
5+
if (typeof graph.getNeighbors !== "function") {
6+
throw "Graph should implement a getNeighbors function";
7+
}
8+
if (typeof source !== "number") {
9+
throw "source should be a number";
10+
}
11+
12+
const stack = [], // The stack that will be used
13+
order = [], // Array to hold the order of visit. Mainly for unit testing
14+
visited = {}; // Keep track of visited vertices
15+
16+
let found = false;
17+
stack.push(source);
18+
visited[source] = true;
19+
while (stack.length !== 0) {
20+
const currentVertex = stack.pop();
21+
order.push(currentVertex);
22+
const neighbors = graph.getNeighbors(currentVertex);
23+
for (const neighbor of neighbors) {
24+
if (!visited[neighbor]) {
25+
stack.push(neighbor);
26+
visited[neighbor] = true;
27+
if (neighbor === target) {
28+
found = true;
29+
}
30+
}
31+
}
32+
}
33+
return { order, found };
34+
};
35+
36+
const GraphFactory = (() => {
37+
const GraphTemplate = {
38+
init() {
39+
this._graph = [];
40+
},
41+
getNeighbors(vertex) {
42+
return this._graph[vertex] || [];
43+
},
44+
addEdge(source, target, biDirectional = true) {
45+
this._addEdge(source, target);
46+
if (biDirectional) {
47+
this._addEdge(target, source);
48+
}
49+
},
50+
_addEdge(source, target) {
51+
this._graph[source] = this._graph[source] || [];
52+
this._graph[source].push(target);
53+
},
54+
printGraph() {
55+
console.log(JSON.stringify(this._graph, null, 2));
56+
}
57+
};
58+
59+
return {
60+
getGraph() {
61+
const Graph = Object.assign({}, GraphTemplate);
62+
Graph.init();
63+
return Graph;
64+
}
65+
};
66+
})();
67+
68+
describe("DFS", () => {
69+
let graph = null;
70+
71+
beforeEach(() => {
72+
graph = GraphFactory.getGraph();
73+
});
74+
75+
it("should throw error on bad graph", () => {
76+
expect(() => {
77+
DFS({});
78+
}).toThrow("Graph should implement a getNeighbors function");
79+
});
80+
81+
it("should throw error on no source vertex", () => {
82+
expect(() => {
83+
DFS(graph);
84+
}).toThrow("source should be a number");
85+
});
86+
87+
it("simple bi-directional graph where target is reachable", () => {
88+
graph.addEdge(0, 1);
89+
graph.addEdge(0, 3);
90+
graph.addEdge(1, 2);
91+
expect(DFS(graph, 0, 3)).toEqual({
92+
order: [0, 3, 1, 2],
93+
found: true
94+
});
95+
});
96+
97+
it("complex bi-directional graph where target is reachable", () => {
98+
graph.addEdge(0, 1);
99+
graph.addEdge(0, 2);
100+
graph.addEdge(1, 3);
101+
graph.addEdge(3, 4);
102+
graph.addEdge(4, 2);
103+
expect(DFS(graph, 0, 3)).toEqual({
104+
order: [0, 2, 4, 3, 1],
105+
found: true
106+
});
107+
});
108+
109+
it("complex uni-directional graph where target is reachable", () => {
110+
graph.addEdge(0, 1, false);
111+
graph.addEdge(0, 2, false);
112+
graph.addEdge(1, 3, false);
113+
graph.addEdge(3, 4, false);
114+
graph.addEdge(4, 2, false);
115+
expect(DFS(graph, 0, 3)).toEqual({
116+
order: [0, 2, 1, 3, 4],
117+
found: true
118+
});
119+
});
120+
121+
it("simple bi-directional graph where target is not present", () => {
122+
graph.addEdge(0, 1);
123+
graph.addEdge(0, 3);
124+
graph.addEdge(1, 2);
125+
expect(DFS(graph, 0, 5)).toEqual({
126+
order: [0, 3, 1, 2],
127+
found: false
128+
});
129+
});
130+
});

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Borwein's Algorithm | :+1: | | | | :+1: | | | | ||
1717
BubbleSort | :+1: | :+1: | :+1: | :+1: | :+1: | :+1: | | :+1: | :+1: |
1818
Conjugate Gradient | | | | | :+1: | | | | ||
1919
CountingSort | :+1: | :+1: | | | :+1: | | | | |
20-
DepthFirstSearch | :+1: | :+1: | | | :+1: | | | | |
20+
DepthFirstSearch | :+1: | :+1: | | | :+1: | :+1: | | | |
2121
Dijkstra's | :+1: | :+1: | | | :+1: | | | | |
2222
Doomsday | :+1: | :+1: | | | | :+1: | | | | :+1: | :+1:
2323
EditDistance | | | | | :+1: | | | |

0 commit comments

Comments
 (0)