Skip to content

Commit efc2d6d

Browse files
authored
Merge pull request #33 from Debashis08/feature-graph-implementation
Feature graph implementation
2 parents 764ee18 + 4650c74 commit efc2d6d

File tree

6 files changed

+178
-0
lines changed

6 files changed

+178
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# pragma once
2+
3+
#include<map>
4+
#include<vector>
5+
#include<set>
6+
using namespace std;
7+
8+
namespace MinimumSpanningTreePrimAlgorithm
9+
{
10+
class Node
11+
{
12+
public:
13+
int data;
14+
Node* parent;
15+
int key;
16+
bool isInOperationalSet;
17+
Node(int data);
18+
};
19+
20+
class CompareNodeKey
21+
{
22+
public:
23+
bool operator()(const Node* nodeU, const Node* nodeV) const
24+
{
25+
return nodeU->key < nodeV->key;
26+
}
27+
};
28+
29+
class Graph
30+
{
31+
private:
32+
map<Node*, vector<pair<Node*, int>>> _adjlist;
33+
map<int, Node*> _nodeMap;
34+
vector<pair<pair<int, int>, int>> _minimumSpanningTree;
35+
multiset<Node*, CompareNodeKey> _operationalSet;
36+
Node* MakeOrFindNode(int data);
37+
public:
38+
void PushUndirectedEdge(int valueU, int valueV, int weight);
39+
void FindMinimumSpanningTreePrimAlgorithm();
40+
vector<pair<pair<int, int>, int>> GetMinimumSpanningTree();
41+
};
42+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#include "../Headers/0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.h"
2+
#include<climits>
3+
using namespace std;
4+
5+
6+
namespace MinimumSpanningTreePrimAlgorithm
7+
{
8+
Node::Node(int data)
9+
{
10+
this->data = data;
11+
this->parent = nullptr;
12+
this->key = INT_MAX;
13+
this->isInOperationalSet = false;
14+
}
15+
16+
// Graph Private Member Methods
17+
Node* Graph::MakeOrFindNode(int data)
18+
{
19+
Node* node = nullptr;
20+
if (this->_nodeMap.find(data) == this->_nodeMap.end())
21+
{
22+
node = new Node(data);
23+
this->_nodeMap[data] = node;
24+
}
25+
else
26+
{
27+
node = this->_nodeMap[data];
28+
}
29+
return node;
30+
}
31+
32+
// Graph Public Member Methods
33+
void Graph::PushUndirectedEdge(int dataU, int dataV, int weight)
34+
{
35+
Node* nodeU = this->MakeOrFindNode(dataU);
36+
Node* nodeV = this->MakeOrFindNode(dataV);
37+
38+
this->_adjlist[nodeU].push_back({nodeV, weight});
39+
this->_adjlist[nodeV].push_back({nodeU, weight});
40+
}
41+
42+
void Graph::FindMinimumSpanningTreePrimAlgorithm()
43+
{
44+
Node* root = this->_nodeMap.begin()->second;
45+
46+
root->key = 0;
47+
for (auto& iterator : this->_nodeMap)
48+
{
49+
iterator.second->isInOperationalSet = true;
50+
this->_operationalSet.insert(iterator.second);
51+
}
52+
53+
while (!this->_operationalSet.empty())
54+
{
55+
Node* nodeU = *(this->_operationalSet.begin());
56+
this->_operationalSet.erase(nodeU);
57+
nodeU->isInOperationalSet = false;
58+
59+
for (auto& iterator : this->_adjlist[nodeU])
60+
{
61+
Node* nodeV = iterator.first;
62+
int weight = iterator.second;
63+
64+
if (nodeV->isInOperationalSet && weight < nodeV->key)
65+
{
66+
this->_operationalSet.erase(nodeV);
67+
nodeV->key = weight;
68+
nodeV->parent = nodeU;
69+
this->_operationalSet.insert(nodeV);
70+
71+
}
72+
}
73+
74+
if (nodeU->parent != nullptr)
75+
{
76+
this->_minimumSpanningTree.push_back({ {nodeU->parent->data, nodeU->data}, nodeU->key });
77+
}
78+
}
79+
}
80+
81+
vector<pair<pair<int, int>, int>> Graph::GetMinimumSpanningTree()
82+
{
83+
return this->_minimumSpanningTree;
84+
}
85+
}

SourceCodes/0003_Graph/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(0003GRAPH_SOURCES
77
0005_HamiltonianPathAndCycle.cc
88
0006_EulerianPathAndCircuit.cc
99
0007_MinimumSpanningTreeKruskalAlgorithm.cc
10+
0008_MinimumSpanningTreePrimAlgorithm.cc
1011

1112
)
1213

Tests/0000_CommonUtilities/UnitTestHelper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ class UnitTestHelper
150150

151151
sort(data.begin(), data.end(), [](const pair<pair<T, T>, T>& pairA, const pair<pair<T, T>, T>& pairB)
152152
{
153+
if (pairA.second == pairB.second)
154+
{
155+
return pairA.first.first < pairB.first.first;
156+
}
153157
return pairA.second < pairB.second;
154158
});
155159
return data;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include<gtest/gtest.h>
2+
#include "../Headers/0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.h"
3+
#include "../0000_CommonUtilities/UnitTestHelper.h"
4+
5+
namespace MinimumSpanningTreePrimAlgorithm
6+
{
7+
UnitTestHelper unitTestHelper;
8+
9+
TEST(MST, Prim)
10+
{
11+
Graph graph;
12+
13+
graph.PushUndirectedEdge(1, 2, 4);
14+
graph.PushUndirectedEdge(1, 8, 8);
15+
graph.PushUndirectedEdge(2, 8, 11);
16+
graph.PushUndirectedEdge(2, 3, 8);
17+
graph.PushUndirectedEdge(3, 4, 7);
18+
graph.PushUndirectedEdge(3, 9, 2);
19+
graph.PushUndirectedEdge(3, 6, 4);
20+
graph.PushUndirectedEdge(4, 5, 9);
21+
graph.PushUndirectedEdge(4, 6, 14);
22+
graph.PushUndirectedEdge(5, 6, 10);
23+
graph.PushUndirectedEdge(6, 7, 2);
24+
graph.PushUndirectedEdge(7, 8, 1);
25+
graph.PushUndirectedEdge(7, 9, 6);
26+
graph.PushUndirectedEdge(8, 9, 7);
27+
28+
graph.FindMinimumSpanningTreePrimAlgorithm();
29+
30+
vector<pair<pair<int, int>, int>> actualMST = graph.GetMinimumSpanningTree();
31+
vector<pair<pair<int, int>, int>> expectedMST =
32+
{
33+
{{7, 8}, 1},
34+
{{3, 9}, 2},
35+
{{6, 7}, 2},
36+
{{2, 1}, 4},
37+
{{3, 6}, 4},
38+
{{3, 4}, 7},
39+
{{8, 1}, 8},
40+
{{4, 5}, 9}
41+
};
42+
43+
ASSERT_EQ(unitTestHelper.SortVectorOfPair(actualMST), unitTestHelper.SortVectorOfPair(expectedMST));
44+
}
45+
}

Tests/0003_Graph/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ add_executable(
1919
0005_HamiltonianPathAndCycleTest.cc
2020
0006_EulerianPathAndCircuitTest.cc
2121
0007_MinimumSpanningTreeKruskalAlgorithmTest.cc
22+
0008_MinimumSpanningTreePrimAlgorithmTest.cc
2223
)
2324

2425
target_link_libraries(

0 commit comments

Comments
 (0)