-
Notifications
You must be signed in to change notification settings - Fork 0
/
topological-sorting.cpp
101 lines (81 loc) · 3.16 KB
/
topological-sorting.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <vector>
#include <map>
#include <unordered_set>
using namespace std;
/**
* Definition for Directed graph.
*/
struct DirectedGraphNode {
int label;
vector<DirectedGraphNode *> neighbors;
DirectedGraphNode(int x) : label(x) {};
};
class Solution {
void addIncomingConnection(DirectedGraphNode* node,
map<DirectedGraphNode*, int> &incomingConnections) {
auto it = incomingConnections.find(node);
if (it == incomingConnections.end()) {
incomingConnections[node] = 1;
} else {
incomingConnections[node] = incomingConnections[node] + 1;
}
}
void calculateIncomingConnections(vector<DirectedGraphNode*> &graph,
map<DirectedGraphNode*, int> &incomingConnections,
unordered_set<DirectedGraphNode*> &visited) {
for (auto &node : graph) {
auto it = incomingConnections.find(node);
if (it == incomingConnections.end()) {
incomingConnections[node] = 0;
}
if (visited.emplace(node).second) {
for (auto &neighbor : node->neighbors) {
addIncomingConnection(neighbor, incomingConnections);
}
calculateIncomingConnections(node->neighbors, incomingConnections, visited);
}
}
}
queue<DirectedGraphNode *> getRoots(map<DirectedGraphNode*, int> &incomingConnections) {
queue<DirectedGraphNode*> roots;
for (auto &pair : incomingConnections) {
if (pair.second == 0) {
//cout << "found a root" << pair.first->label << endl;
roots.emplace(pair.first);
}
}
return roots;
}
vector<DirectedGraphNode *> topSort(vector<DirectedGraphNode*> &graph,
map<DirectedGraphNode*, int> &incomingConnections) {
vector<DirectedGraphNode*> result;
queue<DirectedGraphNode*> roots = getRoots(incomingConnections);
while (!roots.empty()) {
DirectedGraphNode* node = roots.front();
roots.pop();
result.push_back(node);
for (auto &neighbor : node->neighbors) {
--incomingConnections[neighbor];
if (incomingConnections[neighbor] == 0) {
//cout << "adding node as a root" << neighbor->label << endl;
roots.emplace(neighbor);
}
}
}
return result;
}
public:
/**
* @param graph: A list of Directed graph node
* @return: Any topological order for the given graph.
*/
vector<DirectedGraphNode*> topSort(vector<DirectedGraphNode*> graph) {
map<DirectedGraphNode*, int> incomingConnections;
unordered_set<DirectedGraphNode*> visited;
calculateIncomingConnections(graph, incomingConnections, visited);
/*for (auto &pair : incomingConnections) {
cout << pair.first->label << " has " << pair.second << " incoming connections" << endl;
}*/
return topSort(graph, incomingConnections);
}
};