TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
topological_sort.cpp
Go to the documentation of this file.
1
15#include <algorithm> // For std::reverse
16#include <cassert> // For assert
17#include <iostream> // For IO operations
18#include <stack> // For std::stack
19#include <stdexcept> // For std::invalid_argument
20#include <vector> // For std::vector
21
26namespace graph {
27
32namespace topological_sort {
38class Graph {
39 private:
40 int n; // Number of nodes
41 std::vector<std::vector<int>> adj; // Adjacency list representation
42
43 public:
48 Graph(int nodes) : n(nodes), adj(nodes) {}
49
55 void addEdge(int u, int v) { adj[u].push_back(v); }
56
61 const std::vector<std::vector<int>>& getAdjacencyList() const {
62 return adj;
63 }
64
69 int getNumNodes() const { return n; }
70};
71
79void dfs(int v, std::vector<int>& visited,
80 const std::vector<std::vector<int>>& graph, std::stack<int>& s) {
81 visited[v] = 1;
82 for (int neighbour : graph[v]) {
83 if (!visited[neighbour]) {
84 dfs(neighbour, visited, graph, s);
85 }
86 }
87 s.push(v);
88}
89
95std::vector<int> topologicalSort(const Graph& g) {
96 int n = g.getNumNodes();
97 const auto& adj = g.getAdjacencyList();
98 std::vector<int> visited(n, 0);
99 std::stack<int> s;
100
101 for (int i = 0; i < n; i++) {
102 if (!visited[i]) {
103 dfs(i, visited, adj, s);
104 }
105 }
106
107 std::vector<int> ans;
108 while (!s.empty()) {
109 int elem = s.top();
110 s.pop();
111 ans.push_back(elem);
112 }
113
114 if (ans.size() < n) { // Cycle detected
115 throw std::invalid_argument("cycle detected in graph");
116 }
117 return ans;
118}
119} // namespace topological_sort
120} // namespace graph
121
126static void test() {
127 // Test 1
128 std::cout << "Testing for graph 1\n";
129 int n_1 = 6;
131 graph1.addEdge(4, 0);
132 graph1.addEdge(5, 0);
133 graph1.addEdge(5, 2);
134 graph1.addEdge(2, 3);
135 graph1.addEdge(3, 1);
136 graph1.addEdge(4, 1);
137 std::vector<int> ans_1 = graph::topological_sort::topologicalSort(graph1);
138 std::vector<int> expected_1 = {5, 4, 2, 3, 1, 0};
139 std::cout << "Topological Sorting Order: ";
140 for (int i : ans_1) {
141 std::cout << i << " ";
142 }
143 std::cout << '\n';
144 assert(ans_1 == expected_1);
145 std::cout << "Test Passed\n\n";
146
147 // Test 2
148 std::cout << "Testing for graph 2\n";
149 int n_2 = 5;
151 graph2.addEdge(0, 1);
152 graph2.addEdge(0, 2);
153 graph2.addEdge(1, 2);
154 graph2.addEdge(2, 3);
155 graph2.addEdge(1, 3);
156 graph2.addEdge(2, 4);
157 std::vector<int> ans_2 = graph::topological_sort::topologicalSort(graph2);
158 std::vector<int> expected_2 = {0, 1, 2, 4, 3};
159 std::cout << "Topological Sorting Order: ";
160 for (int i : ans_2) {
161 std::cout << i << " ";
162 }
163 std::cout << '\n';
164 assert(ans_2 == expected_2);
165 std::cout << "Test Passed\n\n";
166
167 // Test 3 - Graph with cycle
168 std::cout << "Testing for graph 3\n";
169 int n_3 = 3;
171 graph3.addEdge(0, 1);
172 graph3.addEdge(1, 2);
173 graph3.addEdge(2, 0);
174 try {
175 graph::topological_sort::topologicalSort(graph3);
176 } catch (std::invalid_argument& err) {
177 assert(std::string(err.what()) == "cycle detected in graph");
178 }
179 std::cout << "Test Passed\n";
180}
181
186int main() {
187 test(); // run self test implementations
188 return 0;
189}
Class that represents a directed graph and provides methods for manipulating the graph.
void addEdge(int u, int v)
Function that adds an edge between two nodes or vertices of graph.
const std::vector< std::vector< int > > & getAdjacencyList() const
Get the adjacency list of the graph.
Graph(int nodes)
Constructor for the Graph class.
int getNumNodes() const
Get the number of nodes in the graph.
Graph Algorithms.
Topological Sort Algorithm.
std::vector< int > topologicalSort(const Graph &g)
Function to get the topological sort of the graph.
static void test()
Self-test implementation.
int main()
Main function.