Skip to content

Commit e9c4851

Browse files
authored
Merge pull request #23 from Debashis08/feature-graph-implementation
Feature graph implementation
2 parents d3e4d1b + f16d882 commit e9c4851

File tree

7 files changed

+212
-1
lines changed

7 files changed

+212
-1
lines changed

Headers/0003_Graph/0003_TopologicalSort.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ class TopologicalSortGraph
2525
bool hasCycle;
2626
map<TopologicalSortNode*, list<TopologicalSortNode*>> _adjlist;
2727
map<int, TopologicalSortNode*> _nodeMap;
28-
TopologicalSortNode* MakeOrFindNode(int value);
2928
list<TopologicalSortNode*> _topologicalSortedNodeList;
29+
TopologicalSortNode* MakeOrFindNode(int value);
3030
void DepthFirstSearch(TopologicalSortNode* DFSNode);
3131
public:
3232
void PushDirectedEdge(int valueU, int valueV);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
#include<list>
4+
#include<map>
5+
#include<string>
6+
#include<vector>
7+
using namespace std;
8+
enum color { WHITE, GRAY, BLACK };
9+
10+
class SCCNode
11+
{
12+
public:
13+
int data;
14+
int color;
15+
int discoveryTime;
16+
int finishingTime;
17+
SCCNode* parent;
18+
SCCNode(int value);
19+
};
20+
21+
class StronglyConnectedComponentsGraph
22+
{
23+
private:
24+
int time;
25+
map<SCCNode*, list<SCCNode*>> _adjlistG;
26+
map<SCCNode*, list<SCCNode*>> _adjlistT;
27+
map<int, SCCNode*> _nodeMap;
28+
list<SCCNode*> _nodesFinishingTimeOrder;
29+
vector<vector<int>> _allConnectedComponents;
30+
SCCNode* MakeOrFindNode(int value);
31+
void DepthFirstSearchOnGraphG(SCCNode* DFSNode);
32+
void DepthFirstSearchOnGraphT(SCCNode* DFSNode, vector<int>& connectedComponents);
33+
public:
34+
void PushDirectedEdge(int valueU, int valueV);
35+
void PushSingleNode(int valueU);
36+
void DFSOnGraphG();
37+
void DFSOnGraphT();
38+
vector<vector<int>> FindAllStronglyConnectedComponents();
39+
};
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include "../Headers/0003_Graph/0004_StronglyConnectedComponents.h"
2+
#include<vector>
3+
#include<utility>
4+
#include<climits>
5+
using namespace std;
6+
7+
SCCNode::SCCNode(int value)
8+
{
9+
this->data = value;
10+
this->discoveryTime = INT_MAX;
11+
this->finishingTime = INT_MAX;
12+
this->color = WHITE;
13+
this->parent = nullptr;
14+
}
15+
16+
SCCNode* StronglyConnectedComponentsGraph::MakeOrFindNode(int value)
17+
{
18+
SCCNode* node = nullptr;
19+
if (this->_nodeMap.find(value) == this->_nodeMap.end())
20+
{
21+
node = new SCCNode(value);
22+
this->_nodeMap[value] = node;
23+
}
24+
else
25+
{
26+
node = this->_nodeMap[value];
27+
}
28+
return node;
29+
}
30+
31+
void StronglyConnectedComponentsGraph::DepthFirstSearchOnGraphG(SCCNode* nodeU)
32+
{
33+
this->time++;
34+
nodeU->discoveryTime = this->time;
35+
nodeU->color = GRAY;
36+
for (auto nodeV : this->_adjlistG[nodeU])
37+
{
38+
if (nodeV->color == WHITE)
39+
{
40+
nodeV->parent = nodeU;
41+
this->DepthFirstSearchOnGraphG(nodeV);
42+
}
43+
}
44+
nodeU->color = BLACK;
45+
this->time++;
46+
nodeU->finishingTime = time;
47+
this->_nodesFinishingTimeOrder.push_front(nodeU);
48+
}
49+
50+
void StronglyConnectedComponentsGraph::DepthFirstSearchOnGraphT(SCCNode* nodeU, vector<int>& connectedComponents)
51+
{
52+
nodeU->color = GRAY;
53+
connectedComponents.push_back(nodeU->data);
54+
for (auto nodeV : this->_adjlistT[nodeU])
55+
{
56+
if (nodeV->color == WHITE)
57+
{
58+
nodeV->parent = nodeU;
59+
this->DepthFirstSearchOnGraphT(nodeV, connectedComponents);
60+
}
61+
}
62+
nodeU->color = BLACK;
63+
}
64+
65+
void StronglyConnectedComponentsGraph::PushDirectedEdge(int valueU, int valueV)
66+
{
67+
SCCNode* nodeU = this->MakeOrFindNode(valueU);
68+
SCCNode* nodeV = this->MakeOrFindNode(valueV);
69+
70+
// Creating the actual graph.
71+
this->_adjlistG[nodeU].push_back(nodeV);
72+
73+
// Creating the transpose of the actual graph.
74+
this->_adjlistT[nodeV].push_back(nodeU);
75+
}
76+
77+
void StronglyConnectedComponentsGraph::PushSingleNode(int valueU)
78+
{
79+
SCCNode* nodeU = this->MakeOrFindNode(valueU);
80+
}
81+
82+
void StronglyConnectedComponentsGraph::DFSOnGraphG()
83+
{
84+
this->time = 0;
85+
for (auto& iterator : this->_nodeMap)
86+
{
87+
if (iterator.second->color == WHITE)
88+
{
89+
this->DepthFirstSearchOnGraphG(iterator.second);
90+
}
91+
}
92+
}
93+
94+
void StronglyConnectedComponentsGraph::DFSOnGraphT()
95+
{
96+
for (auto& iterator : this->_nodeMap)
97+
{
98+
iterator.second->color = WHITE;
99+
iterator.second->parent = nullptr;
100+
}
101+
102+
for (auto& iterator : this->_nodesFinishingTimeOrder)
103+
{
104+
if (iterator->color == WHITE)
105+
{
106+
vector<int> connectedComponents;
107+
this->DepthFirstSearchOnGraphT(iterator, connectedComponents);
108+
this->_allConnectedComponents.push_back(connectedComponents);
109+
}
110+
}
111+
}
112+
113+
vector<vector<int>> StronglyConnectedComponentsGraph::FindAllStronglyConnectedComponents()
114+
{
115+
this->DFSOnGraphG();
116+
this->DFSOnGraphT();
117+
return this->_allConnectedComponents;
118+
}

SourceCodes/0003_Graph/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set(0003GRAPH_SOURCES
33
0001_BreadthFirstSearch.cc
44
0002_DepthFirstSearch.cc
55
0003_TopologicalSort.cc
6+
0004_StronglyConnectedComponents.cc
67
)
78

89
# Create a library target

Tests/0000_CommonUtilities/UnitTestHelper.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,24 @@ class UnitTestHelper
5151
}
5252
return result;
5353
}
54+
55+
template<typename T>
56+
string VerifyVectorResult(vector<vector<T>> vector)
57+
{
58+
string result = "";
59+
for (auto& iterator : vector)
60+
{
61+
result += "[";
62+
for (auto& it : iterator)
63+
{
64+
result += to_string(it) + " ";
65+
}
66+
if (!result.empty())
67+
{
68+
result.pop_back();
69+
}
70+
result += "]";
71+
}
72+
return result;
73+
}
5474
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include<gtest/gtest.h>
2+
#include "../Headers/0003_Graph/0004_StronglyConnectedComponents.h"
3+
#include "../0000_CommonUtilities/UnitTestHelper.h"
4+
5+
namespace StronglyConnectedComponentsTest
6+
{
7+
UnitTestHelper unitTestHelper;
8+
9+
TEST(StronglyConnectedComponentsTesting, SimpleGraphTest)
10+
{
11+
StronglyConnectedComponentsGraph graph;
12+
13+
graph.PushDirectedEdge(1, 2);
14+
graph.PushDirectedEdge(1, 5);
15+
graph.PushDirectedEdge(2, 3);
16+
graph.PushDirectedEdge(2, 4);
17+
graph.PushDirectedEdge(3, 2);
18+
graph.PushDirectedEdge(4, 4);
19+
graph.PushDirectedEdge(5, 1);
20+
graph.PushDirectedEdge(5, 4);
21+
graph.PushDirectedEdge(6, 1);
22+
graph.PushDirectedEdge(6, 3);
23+
graph.PushDirectedEdge(6, 7);
24+
graph.PushDirectedEdge(7, 3);
25+
graph.PushDirectedEdge(7, 8);
26+
graph.PushDirectedEdge(8, 6);
27+
28+
string actualResult = unitTestHelper.VerifyVectorResult(graph.FindAllStronglyConnectedComponents());
29+
string expectedResult = "[6 8 7][1 5][2 3][4]";
30+
EXPECT_EQ(actualResult, expectedResult);
31+
}
32+
}

Tests/0003_Graph/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_executable(
1515
0001_BreadthFirstSearchTest.cc
1616
0002_DepthFirstSearchTest.cc
1717
0003_TopologicalSortTest.cc
18+
0004_StronglyConnectedComponentsTest.cc
1819
)
1920

2021
target_link_libraries(

0 commit comments

Comments
 (0)