26
26
namespace graph {
27
27
28
28
/* *
29
- * @brief Function that add edge between two nodes or vertices of graph
30
- * @param u any node or vertex of graph
31
- * @param v any node or vertex of graph
32
- * @returns None
29
+ * @class Graph
30
+ * @brief Class that represents a directed graph and provides methods for
31
+ * manipulating the graph
33
32
*/
34
- void addEdge (std::vector<std::vector<int >>& adj, int u, int v) {
35
- adj[u].push_back (v);
36
- }
33
+ class Graph {
34
+ private:
35
+ int n; // Number of nodes
36
+ std::vector<std::vector<int >> adj; // Adjacency list representation
37
+
38
+ public:
39
+ /* *
40
+ * @brief Constructor for the Graph class
41
+ * @param nodes Number of nodes in the graph
42
+ */
43
+ Graph (int nodes) : n(nodes), adj(nodes) {}
44
+
45
+ /* *
46
+ * @brief Function that adds an edge between two nodes or vertices of graph
47
+ * @param u Start node of the edge
48
+ * @param v End node of the edge
49
+ */
50
+ void addEdge (int u, int v) { adj[u].push_back (v); }
51
+
52
+ /* *
53
+ * @brief Get the adjacency list of the graph
54
+ * @returns A reference to the adjacency list
55
+ */
56
+ const std::vector<std::vector<int >>& getAdjacencyList () const {
57
+ return adj;
58
+ }
59
+
60
+ /* *
61
+ * @brief Get the number of nodes in the graph
62
+ * @returns The number of nodes
63
+ */
64
+ int getNumNodes () const { return n; }
65
+ };
37
66
38
67
/* *
39
68
* @brief Function to perform Depth First Search on the graph
40
- * @param v starting vertex for depth first search
41
- * @param vistied array representing if a node is visited
42
- * @param graph adjecancy list of the graph
43
- * @param s stack containing the vertex of topological sort
44
- * @returns None
69
+ * @param v Starting vertex for depth-first search
70
+ * @param visited Array representing whether each node has been visited
71
+ * @param graph Adjacency list of the graph
72
+ * @param s Stack containing the vertices for topological sorting
45
73
*/
46
- void dfs (int v, std::vector<int >& visited, std::vector<std::vector< int >>& graph,
47
- std::stack<int >& s) {
74
+ void dfs (int v, std::vector<int >& visited,
75
+ const std::vector<std::vector< int >>& graph, std::stack<int >& s) {
48
76
visited[v] = 1 ;
49
- for (int i = 0 ; i < graph[v].size (); i++) {
50
- int neighbour = graph[v][i];
77
+ for (int neighbour : graph[v]) {
51
78
if (!visited[neighbour]) {
52
79
dfs (neighbour, visited, graph, s);
53
80
}
@@ -57,25 +84,30 @@ void dfs(int v, std::vector<int>& visited, std::vector<std::vector<int>>& graph,
57
84
58
85
/* *
59
86
* @brief Function to get the topological sort of the graph
60
- * @param graph adjecancy list of the graph
61
- * @param n number of nodes in the graph
87
+ * @param g Graph object
88
+ * @returns A vector containing the topological order of nodes
62
89
*/
63
- std::vector<int > topological_sort (std::vector<std::vector<int >>& graph, int n) {
90
+ std::vector<int > topologicalSort (const Graph& g) {
91
+ int n = g.getNumNodes ();
92
+ const auto & adj = g.getAdjacencyList ();
64
93
std::vector<int > visited (n, 0 );
65
94
std::stack<int > s;
95
+
66
96
for (int i = 0 ; i < n; i++) {
67
97
if (!visited[i]) {
68
- dfs (i, visited, graph , s);
98
+ dfs (i, visited, adj , s);
69
99
}
70
100
}
101
+
71
102
std::vector<int > ans;
72
103
while (!s.empty ()) {
73
104
int elem = s.top ();
74
105
s.pop ();
75
106
ans.push_back (elem);
76
107
}
108
+
77
109
if (ans.size () < n) { // Cycle detected
78
- throw std::invalid_argument (" cycle present in graph" );
110
+ throw std::invalid_argument (" cycle detected in graph" );
79
111
}
80
112
return ans;
81
113
}
@@ -86,17 +118,17 @@ std::vector<int> topological_sort(std::vector<std::vector<int>>& graph, int n) {
86
118
* @returns void
87
119
*/
88
120
static void test () {
89
- // Test 1;
121
+ // Test 1
90
122
std::cout << " Testing for graph 1\n " ;
91
123
int n_1 = 6 ;
92
- std::vector<std::vector< int >> adj_1 (n_1);
93
- graph:: addEdge (adj_1, 4 , 0 );
94
- graph:: addEdge (adj_1, 5 , 0 );
95
- graph:: addEdge (adj_1, 5 , 2 );
96
- graph:: addEdge (adj_1, 2 , 3 );
97
- graph:: addEdge (adj_1, 3 , 1 );
98
- graph:: addEdge (adj_1, 4 , 1 );
99
- std::vector<int > ans_1 = graph::topological_sort (adj_1, n_1 );
124
+ graph::Graph graph1 (n_1);
125
+ graph1. addEdge (4 , 0 );
126
+ graph1. addEdge (5 , 0 );
127
+ graph1. addEdge (5 , 2 );
128
+ graph1. addEdge (2 , 3 );
129
+ graph1. addEdge (3 , 1 );
130
+ graph1. addEdge (4 , 1 );
131
+ std::vector<int > ans_1 = graph::topologicalSort (graph1 );
100
132
std::vector<int > expected_1 = {5 , 4 , 2 , 3 , 1 , 0 };
101
133
std::cout << " Topological Sorting Order: " ;
102
134
for (int i : ans_1) {
@@ -109,14 +141,14 @@ static void test() {
109
141
// Test 2
110
142
std::cout << " Testing for graph 2\n " ;
111
143
int n_2 = 5 ;
112
- std::vector<std::vector< int >> adj_2 (n_2);
113
- graph:: addEdge (adj_2, 0 , 1 );
114
- graph:: addEdge (adj_2, 0 , 2 );
115
- graph:: addEdge (adj_2, 1 , 2 );
116
- graph:: addEdge (adj_2, 2 , 3 );
117
- graph:: addEdge (adj_2, 1 , 3 );
118
- graph:: addEdge (adj_2, 2 , 4 );
119
- std::vector<int > ans_2 = graph::topological_sort (adj_2, n_2 );
144
+ graph::Graph graph2 (n_2);
145
+ graph2. addEdge (0 , 1 );
146
+ graph2. addEdge (0 , 2 );
147
+ graph2. addEdge (1 , 2 );
148
+ graph2. addEdge (2 , 3 );
149
+ graph2. addEdge (1 , 3 );
150
+ graph2. addEdge (2 , 4 );
151
+ std::vector<int > ans_2 = graph::topologicalSort (graph2 );
120
152
std::vector<int > expected_2 = {0 , 1 , 2 , 4 , 3 };
121
153
std::cout << " Topological Sorting Order: " ;
122
154
for (int i : ans_2) {
@@ -129,23 +161,23 @@ static void test() {
129
161
// Test 3 - Graph with cycle
130
162
std::cout << " Testing for graph 3\n " ;
131
163
int n_3 = 3 ;
132
- std::vector<std::vector< int >> adj_3 (n_3);
133
- graph:: addEdge (adj_3, 0 , 1 );
134
- graph:: addEdge (adj_3, 1 , 2 );
135
- graph:: addEdge (adj_3, 2 , 0 );
164
+ graph::Graph graph3 (n_3);
165
+ graph3. addEdge (0 , 1 );
166
+ graph3. addEdge (1 , 2 );
167
+ graph3. addEdge (2 , 0 );
136
168
try {
137
- graph::topological_sort (adj_3, n_3 );
169
+ graph::topologicalSort (graph3 );
138
170
} catch (std::invalid_argument& err) {
139
171
assert (std::string (err.what ()) == " cycle detected in graph" );
140
172
}
141
- std::cout << " Test Passed \n " ;
173
+ std::cout << " Test Passed\n " ;
142
174
}
143
175
144
176
/* *
145
177
* @brief Main function
146
178
* @returns 0 on exit
147
179
*/
148
180
int main () {
149
- test (); // Self - test implementation
181
+ test ();
150
182
return 0 ;
151
183
}
0 commit comments