2
2
*
3
3
* @file
4
4
* @brief [Depth First Search Algorithm using Stack
5
- * (Depth First Search
6
- * Algorithm)](https://en.wikipedia.org/wiki/Depth-first_search)
5
+ * (Depth First Search Algorithm)](https://en.wikipedia.org/wiki/Depth-first_search)
7
6
*
8
7
* @author [Ayaan Khan](http://github.com/ayaankhan98)
9
8
* @author [Saurav Uppoor](https://github.com/sauravUppoor)
25
24
* <h4>Working</h4>
26
25
* 1. Mark all vertices as unvisited (colour it WHITE).
27
26
* 2. Push starting vertex into the stack and colour it GREY.
28
- * 3. Once a node is popped out of the stack and is coloured GREY, we colour it
29
- * BLACK.
27
+ * 3. Once a node is popped out of the stack and is coloured GREY, we colour it BLACK.
30
28
* 4. Push all its neighbours which are not coloured BLACK.
31
29
* 5. Repeat steps 4 and 5 until the stack is empty.
32
30
*/
33
31
34
- #include < stdint.h> // for int16_t, int64_t
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
35
37
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
-
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
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
46
41
constexpr int64_t INF = std::numeric_limits<int16_t >::max();
47
42
43
+
48
44
/* *
49
45
* @namespace graph
50
46
* @brief Graph algorithms
51
47
*/
52
48
namespace graph {
53
49
/* *
54
50
* @namespace depth_first_search
55
- * @brief Functions for [Depth First
56
- * Search](https://en.wikipedia.org/wiki/Depth-first_search) algorithm
51
+ * @brief Functions for [Depth First Search](https://en.wikipedia.org/wiki/Depth-first_search) algorithm
57
52
*/
58
53
namespace depth_first_search {
59
54
/* *
@@ -67,14 +62,14 @@ namespace depth_first_search {
67
62
*
68
63
*/
69
64
void addEdge (std::vector<std::vector<size_t >> *adj, size_t u, size_t v) {
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 );
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 );
78
73
}
79
74
80
75
/* *
@@ -89,8 +84,7 @@ void addEdge(std::vector<std::vector<size_t>> *adj, size_t u, size_t v) {
89
84
* @return vector with nodes stored in the order of DFS traversal
90
85
*
91
86
*/
92
- std::vector<size_t > dfs (const std::vector<std::vector<size_t >> &graph,
93
- size_t start) {
87
+ std::vector<size_t > dfs (const std::vector<std::vector<size_t > > &graph, size_t start) {
94
88
// / checked[i] stores the status of each node
95
89
std::vector<size_t > checked (graph.size (), WHITE), traversed_path;
96
90
@@ -127,51 +121,49 @@ std::vector<size_t> dfs(const std::vector<std::vector<size_t>> &graph,
127
121
* @returns none
128
122
*/
129
123
static void tests () {
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;
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
+
175
167
}
176
168
177
169
/* *
@@ -182,35 +174,34 @@ int main() {
182
174
tests (); // execute the tests
183
175
184
176
size_t vertices = 0 , edges = 0 , start_pos = 1 ;
185
- std::vector<size_t > traversal;
177
+ std::vector<size_t > traversal;
186
178
187
179
std::cout << " Enter the Vertices : " ;
188
- std::cin >> vertices;
189
- std::cout << " Enter the Edges : " ;
190
- std::cin >> edges;
180
+ std::cin >> vertices;
181
+ std::cout << " Enter the Edges : " ;
182
+ std::cin >> edges;
191
183
192
184
// / creating a graph
193
- std::vector<std::vector<size_t >> adj (vertices, std::vector<size_t >());
185
+ std::vector<std::vector<size_t > > adj (vertices, std::vector<size_t >());
194
186
195
187
// / taking input for the edges
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
- }
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
+ }
203
194
204
195
// / taking input for the starting position
205
196
std::cout << " Enter the starting vertex [1,n]: " << std::endl;
206
- std::cin >> start_pos;
207
- start_pos -= 1 ;
208
- traversal = graph::depth_first_search::dfs (adj, start_pos);
197
+ std::cin >> start_pos;
198
+ start_pos -= 1 ;
199
+ traversal = graph::depth_first_search::dfs (adj, start_pos);
209
200
210
201
// / Printing the order of traversal
211
202
for (auto x : traversal) {
212
- std::cout << x << ' ' ;
213
- }
203
+ std::cout << x << ' ' ;
204
+ }
214
205
215
206
return 0 ;
216
207
}
0 commit comments