1+ # Depth-First Search (DFS) Algorithm
2+ #
3+ # DFS is a graph traversal algorithm that explores as far as possible along each branch
4+ # before backtracking. It uses a stack data structure (implemented via recursion here).
5+ #
6+ # Time Complexity: O(V + E) where V is vertices and E is edges
7+ # Space Complexity: O(V) for the visited array and recursion stack
8+ #
9+ # Input: An adjacency list representation of a graph and a starting vertex
10+ # Output: The order in which vertices are visited during DFS traversal
11+
12+ # Recursive DFS function
13+ dfs_recursive <- function (graph , vertex , visited , result ) {
14+ # Mark current vertex as visited
15+ visited [vertex ] <- TRUE
16+ result <- c(result , vertex )
17+
18+ # Visit all unvisited adjacent vertices
19+ if (vertex %in% names(graph )) {
20+ for (neighbor in graph [[as.character(vertex )]]) {
21+ if (! visited [neighbor ]) {
22+ result <- dfs_recursive(graph , neighbor , visited , result )
23+ }
24+ }
25+ }
26+
27+ return (result )
28+ }
29+
30+ # Main DFS function
31+ depth_first_search <- function (graph , start_vertex ) {
32+ # Get all vertices in the graph
33+ all_vertices <- unique(c(names(graph ), unlist(graph )))
34+
35+ # Initialize visited array
36+ visited <- rep(FALSE , max(all_vertices ))
37+ names(visited ) <- 1 : max(all_vertices )
38+
39+ # Perform DFS starting from the given vertex
40+ result <- dfs_recursive(graph , start_vertex , visited , c())
41+
42+ return (result )
43+ }
44+
45+ # Iterative DFS function using explicit stack
46+ dfs_iterative <- function (graph , start_vertex ) {
47+ # Get all vertices in the graph
48+ all_vertices <- unique(c(names(graph ), unlist(graph )))
49+
50+ # Initialize visited array and stack
51+ visited <- rep(FALSE , max(all_vertices ))
52+ names(visited ) <- 1 : max(all_vertices )
53+ stack <- c(start_vertex )
54+ result <- c()
55+
56+ while (length(stack ) > 0 ) {
57+ # Pop vertex from stack
58+ vertex <- stack [length(stack )]
59+ stack <- stack [- length(stack )]
60+
61+ if (! visited [vertex ]) {
62+ # Mark as visited and add to result
63+ visited [vertex ] <- TRUE
64+ result <- c(result , vertex )
65+
66+ # Add all unvisited neighbors to stack (in reverse order to maintain left-to-right traversal)
67+ if (as.character(vertex ) %in% names(graph )) {
68+ neighbors <- graph [[as.character(vertex )]]
69+ for (neighbor in rev(neighbors )) {
70+ if (! visited [neighbor ]) {
71+ stack <- c(stack , neighbor )
72+ }
73+ }
74+ }
75+ }
76+ }
77+
78+ return (result )
79+ }
80+
81+ # Example usage and testing
82+ cat(" === Depth-First Search (DFS) Algorithm ===\n " )
83+
84+ # Create a sample graph as adjacency list
85+ # Graph structure:
86+ # 1
87+ # / \
88+ # 2 3
89+ # / \ \
90+ # 4 5 6
91+ graph <- list (
92+ " 1" = c(2 , 3 ),
93+ " 2" = c(4 , 5 ),
94+ " 3" = c(6 ),
95+ " 4" = c(),
96+ " 5" = c(),
97+ " 6" = c()
98+ )
99+
100+ cat(" Graph structure (adjacency list):\n " )
101+ for (vertex in names(graph )) {
102+ cat(" Vertex" , vertex , " -> [" , paste(graph [[vertex ]], collapse = " , " ), " ]\n " )
103+ }
104+
105+ # Test recursive DFS
106+ cat(" \n Recursive DFS starting from vertex 1:\n " )
107+ result_recursive <- depth_first_search(graph , 1 )
108+ cat(" Traversal order:" , paste(result_recursive , collapse = " -> " ), " \n " )
109+
110+ # Test iterative DFS
111+ cat(" \n Iterative DFS starting from vertex 1:\n " )
112+ result_iterative <- dfs_iterative(graph , 1 )
113+ cat(" Traversal order:" , paste(result_iterative , collapse = " -> " ), " \n " )
114+
115+ # Test with different starting vertex
116+ cat(" \n Recursive DFS starting from vertex 2:\n " )
117+ result_from_2 <- depth_first_search(graph , 2 )
118+ cat(" Traversal order:" , paste(result_from_2 , collapse = " -> " ), " \n " )
119+
120+ # Example with a more complex graph (with cycles)
121+ cat(" \n === Example with Cyclic Graph ===\n " )
122+ cyclic_graph <- list (
123+ " 1" = c(2 , 3 ),
124+ " 2" = c(1 , 4 ),
125+ " 3" = c(1 , 5 ),
126+ " 4" = c(2 , 6 ),
127+ " 5" = c(3 , 6 ),
128+ " 6" = c(4 , 5 )
129+ )
130+
131+ cat(" Cyclic graph structure:\n " )
132+ for (vertex in names(cyclic_graph )) {
133+ cat(" Vertex" , vertex , " -> [" , paste(cyclic_graph [[vertex ]], collapse = " , " ), " ]\n " )
134+ }
135+
136+ cat(" \n DFS on cyclic graph starting from vertex 1:\n " )
137+ cyclic_result <- depth_first_search(cyclic_graph , 1 )
138+ cat(" Traversal order:" , paste(cyclic_result , collapse = " -> " ), " \n " )
0 commit comments