2
2
*
3
3
* @file
4
4
* @brief [Depth First Search Algorithm using Stack
5
- * (Depth First Search Algorithm)](https://en.wikipedia.org/wiki/Depth-first_search)
5
+ * (Depth First Search
6
+ * Algorithm)](https://en.wikipedia.org/wiki/Depth-first_search)
6
7
*
7
8
* @author [Ayaan Khan](http://github.com/ayaankhan98)
8
9
* @author [Saurav Uppoor](https://github.com/sauravUppoor)
24
25
* <h4>Working</h4>
25
26
* 1. Mark all vertices as unvisited (colour it WHITE).
26
27
* 2. Push starting vertex into the stack and colour it GREY.
27
- * 3. Once a node is popped out of the stack and is coloured GREY, we colour it BLACK.
28
+ * 3. Once a node is popped out of the stack and is coloured GREY, we colour it
29
+ * BLACK.
28
30
* 4. Push all its neighbours which are not coloured BLACK.
29
31
* 5. Repeat steps 4 and 5 until the stack is empty.
30
32
*/
31
33
32
- #include < iostream> // / for IO operations
33
- #include < stack> // / header for std::stack
34
- #include < vector> // / header for std::vector
35
- #include < cassert> // / header for preprocessor macro assert()
36
- #include < limits> // / header for limits of integral types
34
+ #include < stdint.h> // for int16_t, int64_t
37
35
38
- constexpr int WHITE = 0 ; // / indicates the node hasn't been explored
39
- constexpr int GREY = 1 ; // / indicates node is in stack waiting to be explored
40
- constexpr int BLACK = 2 ; // / indicates node has already been explored
41
- constexpr int64_t INF = std::numeric_limits<int16_t >::max();
36
+ #include < cassert> // for assert
37
+ #include < cstddef> // for size_t
38
+ #include < iostream> // for basic_ostream, operator<<, char_traits, cout, endl
39
+ #include < limits> // for numeric_limits
40
+ #include < stack> // for stack
41
+ #include < vector> // for vector, operator==
42
42
43
+ constexpr int WHITE = 0 ; // / indicates the node hasn't been explored
44
+ constexpr int GREY = 1 ; // / indicates node is in stack waiting to be explored
45
+ constexpr int BLACK = 2 ; // / indicates node has already been explored
46
+ constexpr int64_t INF = std::numeric_limits<int16_t >::max();
43
47
44
48
/* *
45
49
* @namespace graph
@@ -48,7 +52,8 @@ constexpr int64_t INF = std::numeric_limits<int16_t>::max();
48
52
namespace graph {
49
53
/* *
50
54
* @namespace depth_first_search
51
- * @brief Functions for [Depth First Search](https://en.wikipedia.org/wiki/Depth-first_search) algorithm
55
+ * @brief Functions for [Depth First
56
+ * Search](https://en.wikipedia.org/wiki/Depth-first_search) algorithm
52
57
*/
53
58
namespace depth_first_search {
54
59
/* *
@@ -62,14 +67,14 @@ namespace depth_first_search {
62
67
*
63
68
*/
64
69
void addEdge (std::vector<std::vector<size_t >> *adj, size_t u, size_t v) {
65
- /*
66
- *
67
- * Here we are considering undirected graph that's the
68
- * reason we are adding v to the adjacency list representation of u
69
- * and also adding u to the adjacency list representation of v
70
- *
71
- */
72
- (*adj)[u - 1 ].push_back (v - 1 );
70
+ /*
71
+ *
72
+ * Here we are considering undirected graph that's the
73
+ * reason we are adding v to the adjacency list representation of u
74
+ * and also adding u to the adjacency list representation of v
75
+ *
76
+ */
77
+ (*adj)[u - 1 ].push_back (v - 1 );
73
78
}
74
79
75
80
/* *
@@ -84,7 +89,8 @@ void addEdge(std::vector<std::vector<size_t>> *adj, size_t u, size_t v) {
84
89
* @return vector with nodes stored in the order of DFS traversal
85
90
*
86
91
*/
87
- std::vector<size_t > dfs (const std::vector<std::vector<size_t > > &graph, size_t start) {
92
+ std::vector<size_t > dfs (const std::vector<std::vector<size_t >> &graph,
93
+ size_t start) {
88
94
// / checked[i] stores the status of each node
89
95
std::vector<size_t > checked (graph.size (), WHITE), traversed_path;
90
96
@@ -121,49 +127,51 @@ std::vector<size_t> dfs(const std::vector<std::vector<size_t> > &graph, size_t s
121
127
* @returns none
122
128
*/
123
129
static void tests () {
124
- size_t start_pos;
125
-
126
- // / Test 1
127
- std::cout << " Case 1: " << std::endl;
128
- start_pos = 1 ;
129
- std::vector<std::vector<size_t > > g1 (3 , std::vector<size_t >());
130
-
131
- graph::depth_first_search::addEdge (&g1, 1 , 2 );
132
- graph::depth_first_search::addEdge (&g1, 2 , 3 );
133
- graph::depth_first_search::addEdge (&g1, 3 , 1 );
134
-
135
- std::vector<size_t > expected1 {1 , 2 , 3 }; // / for the above sample data, this is the expected output
136
- assert (graph::depth_first_search::dfs (g1, start_pos - 1 ) == expected1);
137
- std::cout << " Passed" << std::endl;
138
-
139
- // / Test 2
140
- std::cout << " Case 2: " << std::endl;
141
- start_pos = 1 ;
142
- std::vector<std::vector<size_t > > g2 (4 , std::vector<size_t >());
143
-
144
- graph::depth_first_search::addEdge (&g2, 1 , 2 );
145
- graph::depth_first_search::addEdge (&g2, 1 , 3 );
146
- graph::depth_first_search::addEdge (&g2, 2 , 4 );
147
- graph::depth_first_search::addEdge (&g2, 4 , 1 );
148
-
149
- std::vector<size_t > expected2 {1 , 3 , 2 , 4 }; // / for the above sample data, this is the expected output
150
- assert (graph::depth_first_search::dfs (g2, start_pos - 1 ) == expected2);
151
- std::cout << " Passed" << std::endl;
152
-
153
- // / Test 3
154
- std::cout << " Case 3: " << std::endl;
155
- start_pos = 2 ;
156
- std::vector<std::vector<size_t > > g3 (4 , std::vector<size_t >());
157
-
158
- graph::depth_first_search::addEdge (&g3, 1 , 2 );
159
- graph::depth_first_search::addEdge (&g3, 1 , 3 );
160
- graph::depth_first_search::addEdge (&g3, 2 , 4 );
161
- graph::depth_first_search::addEdge (&g3, 4 , 1 );
162
-
163
- std::vector<size_t > expected3 {2 , 4 , 1 , 3 }; // / for the above sample data, this is the expected output
164
- assert (graph::depth_first_search::dfs (g3, start_pos - 1 ) == expected3);
165
- std::cout << " Passed" << std::endl;
166
-
130
+ size_t start_pos;
131
+
132
+ // / Test 1
133
+ std::cout << " Case 1: " << std::endl;
134
+ start_pos = 1 ;
135
+ std::vector<std::vector<size_t >> g1 (3 , std::vector<size_t >());
136
+
137
+ graph::depth_first_search::addEdge (&g1, 1 , 2 );
138
+ graph::depth_first_search::addEdge (&g1, 2 , 3 );
139
+ graph::depth_first_search::addEdge (&g1, 3 , 1 );
140
+
141
+ std::vector<size_t > expected1{
142
+ 1 , 2 , 3 }; // / for the above sample data, this is the expected output
143
+ assert (graph::depth_first_search::dfs (g1, start_pos - 1 ) == expected1);
144
+ std::cout << " Passed" << std::endl;
145
+
146
+ // / Test 2
147
+ std::cout << " Case 2: " << std::endl;
148
+ start_pos = 1 ;
149
+ std::vector<std::vector<size_t >> g2 (4 , std::vector<size_t >());
150
+
151
+ graph::depth_first_search::addEdge (&g2, 1 , 2 );
152
+ graph::depth_first_search::addEdge (&g2, 1 , 3 );
153
+ graph::depth_first_search::addEdge (&g2, 2 , 4 );
154
+ graph::depth_first_search::addEdge (&g2, 4 , 1 );
155
+
156
+ std::vector<size_t > expected2{
157
+ 1 , 3 , 2 , 4 }; // / for the above sample data, this is the expected output
158
+ assert (graph::depth_first_search::dfs (g2, start_pos - 1 ) == expected2);
159
+ std::cout << " Passed" << std::endl;
160
+
161
+ // / Test 3
162
+ std::cout << " Case 3: " << std::endl;
163
+ start_pos = 2 ;
164
+ std::vector<std::vector<size_t >> g3 (4 , std::vector<size_t >());
165
+
166
+ graph::depth_first_search::addEdge (&g3, 1 , 2 );
167
+ graph::depth_first_search::addEdge (&g3, 1 , 3 );
168
+ graph::depth_first_search::addEdge (&g3, 2 , 4 );
169
+ graph::depth_first_search::addEdge (&g3, 4 , 1 );
170
+
171
+ std::vector<size_t > expected3{
172
+ 2 , 4 , 1 , 3 }; // / for the above sample data, this is the expected output
173
+ assert (graph::depth_first_search::dfs (g3, start_pos - 1 ) == expected3);
174
+ std::cout << " Passed" << std::endl;
167
175
}
168
176
169
177
/* *
@@ -174,34 +182,35 @@ int main() {
174
182
tests (); // execute the tests
175
183
176
184
size_t vertices = 0 , edges = 0 , start_pos = 1 ;
177
- std::vector<size_t > traversal;
185
+ std::vector<size_t > traversal;
178
186
179
187
std::cout << " Enter the Vertices : " ;
180
- std::cin >> vertices;
181
- std::cout << " Enter the Edges : " ;
182
- std::cin >> edges;
188
+ std::cin >> vertices;
189
+ std::cout << " Enter the Edges : " ;
190
+ std::cin >> edges;
183
191
184
192
// / creating a graph
185
- std::vector<std::vector<size_t > > adj (vertices, std::vector<size_t >());
193
+ std::vector<std::vector<size_t >> adj (vertices, std::vector<size_t >());
186
194
187
195
// / taking input for the edges
188
- std::cout << " Enter the vertices which have edges between them : " << std::endl;
189
- while (edges--) {
190
- size_t u = 0 , v = 0 ;
191
- std::cin >> u >> v;
192
- graph::depth_first_search::addEdge (&adj, u, v);
193
- }
196
+ std::cout << " Enter the vertices which have edges between them : "
197
+ << std::endl;
198
+ while (edges--) {
199
+ size_t u = 0 , v = 0 ;
200
+ std::cin >> u >> v;
201
+ graph::depth_first_search::addEdge (&adj, u, v);
202
+ }
194
203
195
204
// / taking input for the starting position
196
205
std::cout << " Enter the starting vertex [1,n]: " << std::endl;
197
- std::cin >> start_pos;
198
- start_pos -= 1 ;
199
- traversal = graph::depth_first_search::dfs (adj, start_pos);
206
+ std::cin >> start_pos;
207
+ start_pos -= 1 ;
208
+ traversal = graph::depth_first_search::dfs (adj, start_pos);
200
209
201
210
// / Printing the order of traversal
202
211
for (auto x : traversal) {
203
- std::cout << x << ' ' ;
204
- }
212
+ std::cout << x << ' ' ;
213
+ }
205
214
206
215
return 0 ;
207
216
}
0 commit comments