Skip to content

Commit 5625480

Browse files
Add class "Graph"
1 parent 3816cb0 commit 5625480

File tree

1 file changed

+77
-45
lines changed

1 file changed

+77
-45
lines changed

graph/topological_sort.cpp

Lines changed: 77 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,55 @@
2626
namespace graph {
2727

2828
/**
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
3332
*/
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+
};
3766

3867
/**
3968
* @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
4573
*/
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) {
4876
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]) {
5178
if (!visited[neighbour]) {
5279
dfs(neighbour, visited, graph, s);
5380
}
@@ -57,25 +84,30 @@ void dfs(int v, std::vector<int>& visited, std::vector<std::vector<int>>& graph,
5784

5885
/**
5986
* @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
6289
*/
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();
6493
std::vector<int> visited(n, 0);
6594
std::stack<int> s;
95+
6696
for (int i = 0; i < n; i++) {
6797
if (!visited[i]) {
68-
dfs(i, visited, graph, s);
98+
dfs(i, visited, adj, s);
6999
}
70100
}
101+
71102
std::vector<int> ans;
72103
while (!s.empty()) {
73104
int elem = s.top();
74105
s.pop();
75106
ans.push_back(elem);
76107
}
108+
77109
if (ans.size() < n) { // Cycle detected
78-
throw std::invalid_argument("cycle present in graph");
110+
throw std::invalid_argument("cycle detected in graph");
79111
}
80112
return ans;
81113
}
@@ -86,17 +118,17 @@ std::vector<int> topological_sort(std::vector<std::vector<int>>& graph, int n) {
86118
* @returns void
87119
*/
88120
static void test() {
89-
// Test 1;
121+
// Test 1
90122
std::cout << "Testing for graph 1\n";
91123
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);
100132
std::vector<int> expected_1 = {5, 4, 2, 3, 1, 0};
101133
std::cout << "Topological Sorting Order: ";
102134
for (int i : ans_1) {
@@ -109,14 +141,14 @@ static void test() {
109141
// Test 2
110142
std::cout << "Testing for graph 2\n";
111143
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);
120152
std::vector<int> expected_2 = {0, 1, 2, 4, 3};
121153
std::cout << "Topological Sorting Order: ";
122154
for (int i : ans_2) {
@@ -129,23 +161,23 @@ static void test() {
129161
// Test 3 - Graph with cycle
130162
std::cout << "Testing for graph 3\n";
131163
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);
136168
try {
137-
graph::topological_sort(adj_3, n_3);
169+
graph::topologicalSort(graph3);
138170
} catch (std::invalid_argument& err) {
139171
assert(std::string(err.what()) == "cycle detected in graph");
140172
}
141-
std::cout << "Test Passed \n";
173+
std::cout << "Test Passed\n";
142174
}
143175

144176
/**
145177
* @brief Main function
146178
* @returns 0 on exit
147179
*/
148180
int main() {
149-
test(); // Self - test implementation
181+
test();
150182
return 0;
151183
}

0 commit comments

Comments
 (0)