Skip to content

Commit 4a6cdb0

Browse files
committed
Add Prim.cpp
1 parent 0700257 commit 4a6cdb0

File tree

1 file changed

+224
-0
lines changed
  • 6_Graph_Algorithms/23_Minimum_Spanning_Trees

1 file changed

+224
-0
lines changed
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <map>
4+
#include <queue>
5+
#include <set>
6+
#include <iomanip>
7+
8+
using std::vector;
9+
using std::map;
10+
using std::priority_queue;
11+
using std::set;
12+
13+
class Vertex {
14+
public:
15+
char value;
16+
int key;
17+
Vertex* parent;
18+
19+
explicit Vertex(char value) {
20+
this->value = value;
21+
}
22+
};
23+
24+
25+
class Edge {
26+
public:
27+
Vertex *src, *dst;
28+
int weight;
29+
30+
Edge(Vertex *src, Vertex *dst, int weight) {
31+
this->src = src;
32+
this->dst = dst;
33+
this->weight = weight;
34+
}
35+
};
36+
37+
38+
template<class T>
39+
class min_queue {
40+
public:
41+
vector<T> elements;
42+
43+
void push(T e);
44+
T pop();
45+
int size();
46+
void min_heapify(int pos = 0);
47+
void build_min_heap();
48+
};
49+
50+
template<class T>
51+
int min_queue<T>::size() {
52+
return elements.size();
53+
}
54+
55+
template<class T>
56+
void min_queue<T>::push(T e) {
57+
elements.push_back(e);
58+
}
59+
60+
template<class T>
61+
T min_queue<T>::pop() {
62+
T smallest = elements[0];
63+
elements.erase(elements.begin());
64+
return smallest;
65+
}
66+
67+
template<class T>
68+
void min_queue<T>::build_min_heap() {
69+
for (int i = (elements.size()) / 2 - 1; i >= 0; i--) {
70+
min_heapify(i);
71+
}
72+
}
73+
74+
template<class T>
75+
void min_queue<T>::min_heapify(int pos) {
76+
int leftChild = pos * 2 + 1;
77+
int rightChild = leftChild + 1;
78+
79+
if (leftChild >= elements.size()) {
80+
leftChild = pos;
81+
}
82+
83+
if (rightChild >= elements.size()) {
84+
rightChild = pos;
85+
}
86+
87+
int smallest = pos;
88+
if ( elements[leftChild]->key < elements[smallest]->key ) {
89+
smallest = leftChild;
90+
}
91+
92+
if ( elements[rightChild]->key < elements[smallest]->key ) {
93+
smallest = rightChild;
94+
}
95+
96+
if ( smallest != pos ) {
97+
std::swap(elements[pos], elements[smallest]);
98+
min_heapify(smallest);
99+
}
100+
}
101+
102+
103+
class Graph {
104+
public:
105+
vector<Vertex*> vertices;
106+
map<Vertex*, vector<Edge*>> edges;
107+
108+
Graph();
109+
void addVertex(Vertex *v);
110+
void addEdge(Vertex *src, Vertex *dst, int weight);
111+
void prim(Vertex *r = NULL);
112+
};
113+
114+
Graph::Graph() {}
115+
116+
void Graph::addVertex(Vertex *v) {
117+
vertices.push_back(v);
118+
}
119+
120+
void Graph::addEdge(Vertex *src, Vertex *dst, int weight) {
121+
edges[src].push_back(new Edge(src, dst, weight));
122+
}
123+
124+
void Graph::prim(Vertex *r) {
125+
if ( r == NULL )
126+
r = vertices[0];
127+
128+
min_queue<Vertex *> pendingVertices;
129+
for (Vertex *v : vertices) {
130+
v->parent = NULL;
131+
v->key = INT32_MAX;
132+
133+
pendingVertices.push(v);
134+
}
135+
136+
r->key = 0;
137+
pendingVertices.build_min_heap();
138+
139+
set<Vertex*> completedVertices;
140+
while (pendingVertices.size() != 0) {
141+
Vertex *u = pendingVertices.pop();
142+
for (Edge *e : edges[u]) {
143+
if ( completedVertices.count(e->dst) == 0 &&
144+
e->weight < e->dst->key ) {
145+
e->dst->parent = u;
146+
e->dst->key = e->weight;
147+
}
148+
}
149+
pendingVertices.build_min_heap();
150+
completedVertices.insert(u);
151+
}
152+
153+
std::cout <<"\nMinimum Spanning Tree Edges :\n\n";
154+
std::cout <<"\t Edge | Weight\n";
155+
std::cout <<"\t----------------\n";
156+
for (Vertex* v : completedVertices) {
157+
if ( v->parent == NULL )
158+
continue;
159+
160+
std::cout <<"\t " <<v->parent->value <<" -> " <<v->value
161+
<<" | " <<std::setw(3) <<v->key <<std::endl;
162+
}
163+
}
164+
165+
166+
int main() {
167+
Graph g;
168+
vector<Vertex*> vertices(9);
169+
170+
for (int i = 0; i < 9; i++) {
171+
vertices[i] = new Vertex(97 + i);
172+
g.addVertex(vertices[i]);
173+
}
174+
175+
// edges from 'a'
176+
g.addEdge(vertices[0], vertices[1], 4);
177+
g.addEdge(vertices[0], vertices[7], 8);
178+
179+
// edges from 'b'
180+
g.addEdge(vertices[1], vertices[0], 4);
181+
g.addEdge(vertices[1], vertices[7], 11);
182+
g.addEdge(vertices[1], vertices[2], 8);
183+
184+
// edges from 'c'
185+
g.addEdge(vertices[2], vertices[1], 8);
186+
g.addEdge(vertices[2], vertices[8], 2);
187+
g.addEdge(vertices[2], vertices[5], 4);
188+
g.addEdge(vertices[2], vertices[3], 7);
189+
190+
// edges from 'd'
191+
g.addEdge(vertices[3], vertices[2], 7);
192+
g.addEdge(vertices[3], vertices[5], 14);
193+
g.addEdge(vertices[3], vertices[4], 9);
194+
195+
// edges from 'e'
196+
g.addEdge(vertices[4], vertices[3], 9);
197+
g.addEdge(vertices[4], vertices[5], 10);
198+
199+
// edges from 'f'
200+
g.addEdge(vertices[5], vertices[6], 2);
201+
g.addEdge(vertices[5], vertices[2], 4);
202+
g.addEdge(vertices[5], vertices[3], 14);
203+
g.addEdge(vertices[5], vertices[5], 10);
204+
205+
// edges from 'g'
206+
g.addEdge(vertices[6], vertices[7], 1);
207+
g.addEdge(vertices[6], vertices[8], 6);
208+
g.addEdge(vertices[6], vertices[5], 2);
209+
210+
// edges from 'h'
211+
g.addEdge(vertices[7], vertices[0], 8);
212+
g.addEdge(vertices[7], vertices[1], 11);
213+
g.addEdge(vertices[7], vertices[8], 7);
214+
g.addEdge(vertices[7], vertices[6], 1);
215+
216+
// edges from 'i'
217+
g.addEdge(vertices[8], vertices[7], 7);
218+
g.addEdge(vertices[8], vertices[2], 2);
219+
g.addEdge(vertices[8], vertices[6], 6);
220+
221+
g.prim();
222+
223+
return 0;
224+
}

0 commit comments

Comments
 (0)