Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Depth-first search traversal in Javascript
DFS visits the child vertices before visiting the sibling vertices; that is, it traverses the depth of any particular path before exploring its breadth. A stack (often the program's call stack via recursion) is generally used when implementing the algorithm.
Following is how a DFS works ?
- Visit the adjacent unvisited vertex. Mark it as visited. Display it. Push it in a stack.
- If no adjacent vertex is found, pop up a vertex from the stack. (It will pop up all the vertices from the stack, which do not have adjacent vertices.)
- Repeat Rule 1 and Rule 2 until the stack is empty.
DFS Algorithm Visualization
Complete DFS Implementation
Here's a complete implementation of DFS with both the Graph class and Stack class:
// Stack implementation for DFS
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.isEmpty()) return null;
return this.items.pop();
}
isEmpty() {
return this.items.length === 0;
}
}
// Graph implementation with DFS
class Graph {
constructor() {
this.nodes = [];
this.edges = {};
}
addNode(node) {
this.nodes.push(node);
this.edges[node] = [];
}
addEdge(node1, node2) {
this.edges[node1].push(node2);
this.edges[node2].push(node1); // Undirected graph
}
DFS(startNode) {
let stack = new Stack();
let explored = new Set();
let result = [];
stack.push(startNode);
explored.add(startNode);
while (!stack.isEmpty()) {
let currentNode = stack.pop();
result.push(currentNode);
console.log("Visiting:", currentNode);
// Add all unvisited neighbors to stack
this.edges[currentNode]
.filter(neighbor => !explored.has(neighbor))
.forEach(neighbor => {
explored.add(neighbor);
stack.push(neighbor);
});
}
return result;
}
}
// Test the implementation
let graph = new Graph();
// Add nodes
["A", "B", "C", "D", "E", "F"].forEach(node => {
graph.addNode(node);
});
// Add edges
graph.addEdge("A", "B");
graph.addEdge("A", "C");
graph.addEdge("B", "D");
graph.addEdge("C", "E");
graph.addEdge("D", "F");
console.log("DFS Traversal starting from A:");
let traversalOrder = graph.DFS("A");
console.log("Traversal order:", traversalOrder);
Visiting: A Visiting: C Visiting: E Visiting: B Visiting: D Visiting: F Traversal order: [ 'A', 'C', 'E', 'B', 'D', 'F' ]
Recursive DFS Implementation
DFS can also be implemented using recursion, which implicitly uses the call stack:
class Graph {
constructor() {
this.nodes = [];
this.edges = {};
}
addNode(node) {
this.nodes.push(node);
this.edges[node] = [];
}
addEdge(node1, node2) {
this.edges[node1].push(node2);
this.edges[node2].push(node1);
}
DFSRecursive(startNode, visited = new Set(), result = []) {
visited.add(startNode);
result.push(startNode);
console.log("Visiting:", startNode);
for (let neighbor of this.edges[startNode]) {
if (!visited.has(neighbor)) {
this.DFSRecursive(neighbor, visited, result);
}
}
return result;
}
}
// Test recursive DFS
let graph2 = new Graph();
["X", "Y", "Z", "W"].forEach(node => graph2.addNode(node));
graph2.addEdge("X", "Y");
graph2.addEdge("Y", "Z");
graph2.addEdge("X", "W");
console.log("\nRecursive DFS from X:");
let recursiveResult = graph2.DFSRecursive("X");
console.log("Result:", recursiveResult);
Visiting: X Visiting: Y Visiting: Z Visiting: W Result: [ 'X', 'Y', 'Z', 'W' ]
Key Characteristics
| Aspect | DFS | BFS |
|---|---|---|
| Data Structure | Stack (LIFO) | Queue (FIFO) |
| Memory Usage | Lower (O(h) where h is height) | Higher (O(w) where w is width) |
| Path Type | May not find shortest path | Finds shortest path |
| Use Cases | Topological sort, cycle detection | Shortest path, level-order |
Common Applications
- Maze solving: Finding a path through a maze
- Cycle detection: Detecting cycles in directed/undirected graphs
- Topological sorting: Ordering tasks with dependencies
- Connected components: Finding all connected parts of a graph
Conclusion
DFS is a fundamental graph traversal algorithm that explores as far as possible along each branch before backtracking. It uses a stack data structure and is ideal for problems requiring deep exploration of graph structures, such as pathfinding and cycle detection.
