Implementation of Prim's algorithm in C++
Could anyone comment on what could be done better and if I made any mistakes?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<pair<int, int>, int> Edge; //a, b, length
// A---------B
// length
vector<Edge> prims_algo(vector<vector<int>> graph, int number_of_nodes){
vector<int> unvisited;
vector<int> visited;
vector<Edge> result;
//mark first as visited and mark the rest as unvisited
for (int i = 1; i < number_of_nodes; i++)
unvisited.push_back(i);
visited.push_back(0);
while (!unvisited.empty()) {
vector<Edge> edges_with_lengths;
//put all edges (with their lengths) from nodes that are in visited
for(auto node : visited) {
for (int sec_node = 0; sec_node < number_of_nodes; sec_node++) {
if (graph[node][sec_node] > 0 && find(unvisited.begin(), unvisited.end(), sec_node) != unvisited.end()) {
//add if there is connection and second node is not visited yet
Edge e = make_pair(make_pair(node, sec_node), graph[node][sec_node]);
edges_with_lengths.push_back(e);
}
}
}
//find the shortest edge
pair<pair<int, int>, int> the_shortest;
the_shortest = edges_with_lengths.front();
for(auto i: edges_with_lengths){
if(the_shortest.second > i.second)
the_shortest = i;
}
//add the shortest path to the result
result.push_back(the_shortest);
//remove a node that the shortest edge leads to
unvisited.erase(remove(unvisited.begin(), unvisited.end(), the_shortest.first.second), unvisited.end());
//mark this node as visited
visited.push_back(the_shortest.first.second);
};
return result;
}
int main() {
/*
2 3
(0)--(1)--(2)
| / |
6| 8/ 5 |7
| / |
(3)-------(4)
9 */
vector<vector<int>> graph =
{{{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0},
}};
vector<Edge> result = prims_algo(graph, 5);
for(auto i:result){
cout<<"EDGE [ " <<i.first.first<<", "<<i.first.second<<"], length: "<<i.second<<endl;
}
return 0;
}
c++ algorithm graph
add a comment |
Could anyone comment on what could be done better and if I made any mistakes?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<pair<int, int>, int> Edge; //a, b, length
// A---------B
// length
vector<Edge> prims_algo(vector<vector<int>> graph, int number_of_nodes){
vector<int> unvisited;
vector<int> visited;
vector<Edge> result;
//mark first as visited and mark the rest as unvisited
for (int i = 1; i < number_of_nodes; i++)
unvisited.push_back(i);
visited.push_back(0);
while (!unvisited.empty()) {
vector<Edge> edges_with_lengths;
//put all edges (with their lengths) from nodes that are in visited
for(auto node : visited) {
for (int sec_node = 0; sec_node < number_of_nodes; sec_node++) {
if (graph[node][sec_node] > 0 && find(unvisited.begin(), unvisited.end(), sec_node) != unvisited.end()) {
//add if there is connection and second node is not visited yet
Edge e = make_pair(make_pair(node, sec_node), graph[node][sec_node]);
edges_with_lengths.push_back(e);
}
}
}
//find the shortest edge
pair<pair<int, int>, int> the_shortest;
the_shortest = edges_with_lengths.front();
for(auto i: edges_with_lengths){
if(the_shortest.second > i.second)
the_shortest = i;
}
//add the shortest path to the result
result.push_back(the_shortest);
//remove a node that the shortest edge leads to
unvisited.erase(remove(unvisited.begin(), unvisited.end(), the_shortest.first.second), unvisited.end());
//mark this node as visited
visited.push_back(the_shortest.first.second);
};
return result;
}
int main() {
/*
2 3
(0)--(1)--(2)
| / |
6| 8/ 5 |7
| / |
(3)-------(4)
9 */
vector<vector<int>> graph =
{{{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0},
}};
vector<Edge> result = prims_algo(graph, 5);
for(auto i:result){
cout<<"EDGE [ " <<i.first.first<<", "<<i.first.second<<"], length: "<<i.second<<endl;
}
return 0;
}
c++ algorithm graph
add a comment |
Could anyone comment on what could be done better and if I made any mistakes?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<pair<int, int>, int> Edge; //a, b, length
// A---------B
// length
vector<Edge> prims_algo(vector<vector<int>> graph, int number_of_nodes){
vector<int> unvisited;
vector<int> visited;
vector<Edge> result;
//mark first as visited and mark the rest as unvisited
for (int i = 1; i < number_of_nodes; i++)
unvisited.push_back(i);
visited.push_back(0);
while (!unvisited.empty()) {
vector<Edge> edges_with_lengths;
//put all edges (with their lengths) from nodes that are in visited
for(auto node : visited) {
for (int sec_node = 0; sec_node < number_of_nodes; sec_node++) {
if (graph[node][sec_node] > 0 && find(unvisited.begin(), unvisited.end(), sec_node) != unvisited.end()) {
//add if there is connection and second node is not visited yet
Edge e = make_pair(make_pair(node, sec_node), graph[node][sec_node]);
edges_with_lengths.push_back(e);
}
}
}
//find the shortest edge
pair<pair<int, int>, int> the_shortest;
the_shortest = edges_with_lengths.front();
for(auto i: edges_with_lengths){
if(the_shortest.second > i.second)
the_shortest = i;
}
//add the shortest path to the result
result.push_back(the_shortest);
//remove a node that the shortest edge leads to
unvisited.erase(remove(unvisited.begin(), unvisited.end(), the_shortest.first.second), unvisited.end());
//mark this node as visited
visited.push_back(the_shortest.first.second);
};
return result;
}
int main() {
/*
2 3
(0)--(1)--(2)
| / |
6| 8/ 5 |7
| / |
(3)-------(4)
9 */
vector<vector<int>> graph =
{{{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0},
}};
vector<Edge> result = prims_algo(graph, 5);
for(auto i:result){
cout<<"EDGE [ " <<i.first.first<<", "<<i.first.second<<"], length: "<<i.second<<endl;
}
return 0;
}
c++ algorithm graph
Could anyone comment on what could be done better and if I made any mistakes?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<pair<int, int>, int> Edge; //a, b, length
// A---------B
// length
vector<Edge> prims_algo(vector<vector<int>> graph, int number_of_nodes){
vector<int> unvisited;
vector<int> visited;
vector<Edge> result;
//mark first as visited and mark the rest as unvisited
for (int i = 1; i < number_of_nodes; i++)
unvisited.push_back(i);
visited.push_back(0);
while (!unvisited.empty()) {
vector<Edge> edges_with_lengths;
//put all edges (with their lengths) from nodes that are in visited
for(auto node : visited) {
for (int sec_node = 0; sec_node < number_of_nodes; sec_node++) {
if (graph[node][sec_node] > 0 && find(unvisited.begin(), unvisited.end(), sec_node) != unvisited.end()) {
//add if there is connection and second node is not visited yet
Edge e = make_pair(make_pair(node, sec_node), graph[node][sec_node]);
edges_with_lengths.push_back(e);
}
}
}
//find the shortest edge
pair<pair<int, int>, int> the_shortest;
the_shortest = edges_with_lengths.front();
for(auto i: edges_with_lengths){
if(the_shortest.second > i.second)
the_shortest = i;
}
//add the shortest path to the result
result.push_back(the_shortest);
//remove a node that the shortest edge leads to
unvisited.erase(remove(unvisited.begin(), unvisited.end(), the_shortest.first.second), unvisited.end());
//mark this node as visited
visited.push_back(the_shortest.first.second);
};
return result;
}
int main() {
/*
2 3
(0)--(1)--(2)
| / |
6| 8/ 5 |7
| / |
(3)-------(4)
9 */
vector<vector<int>> graph =
{{{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0},
}};
vector<Edge> result = prims_algo(graph, 5);
for(auto i:result){
cout<<"EDGE [ " <<i.first.first<<", "<<i.first.second<<"], length: "<<i.second<<endl;
}
return 0;
}
c++ algorithm graph
c++ algorithm graph
edited Apr 25 '16 at 10:01
Jamal♦
30.2k11116226
30.2k11116226
asked Apr 25 '16 at 7:36
Mateusz
15919
15919
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Code looks OK.
I would suggest you to do some class instead of Edge:
//typedef pair<pair<int, int>, int> Edge; //a, b, length
struct Edge{
int a;
int b;
int length;
};
Also I suggest to have some predefined type for vector<Edge>
using EdgeContainer = vector<Edge>;
You have duplication near //find the shortest edge, you probably need Edge there
Here the_shortest is probably not initialized. Also you probably might use something from <algorithm> (but I will do it in same way as you).
//find the shortest edge
pair<pair<int, int>, int> the_shortest;
the_shortest = edges_with_lengths.front();
for(auto i: edges_with_lengths){
if(the_shortest.second > i.second)
the_shortest = i;
}
Another probably micro optimization would be to write ++i in loops:
//for (int i = 1; i < number_of_nodes; i++)
for (int i = 1; i < number_of_nodes; ++i){
// ...
}
Also in C++11 main() does not need to return 0;.
1
"Another probably micro optimization would be to write ++i in loops" For this case (integer or other primitive type), there is no optimization gain at all. For user-defined types, you are correct: postincrement involves a copy to be made, whereas preincrement doesn't. So prefer ++i for user-defined types, and then continue to use it for primitive data types if the choice between pre- vs post- increment doesn't matter, for code consistency.
– scottbb
Apr 25 '16 at 12:29
fully agree, but i think is good habit to use it as ++i
– Nick
Apr 25 '16 at 17:42
Agreed, hence the last part of my comment, "continue to use it for primitive data types ... for code consistency"
– scottbb
Apr 25 '16 at 18:06
add a comment |
you have not used priority queue so performance is bad
New contributor
sukumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f126617%2fimplementation-of-prims-algorithm-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Code looks OK.
I would suggest you to do some class instead of Edge:
//typedef pair<pair<int, int>, int> Edge; //a, b, length
struct Edge{
int a;
int b;
int length;
};
Also I suggest to have some predefined type for vector<Edge>
using EdgeContainer = vector<Edge>;
You have duplication near //find the shortest edge, you probably need Edge there
Here the_shortest is probably not initialized. Also you probably might use something from <algorithm> (but I will do it in same way as you).
//find the shortest edge
pair<pair<int, int>, int> the_shortest;
the_shortest = edges_with_lengths.front();
for(auto i: edges_with_lengths){
if(the_shortest.second > i.second)
the_shortest = i;
}
Another probably micro optimization would be to write ++i in loops:
//for (int i = 1; i < number_of_nodes; i++)
for (int i = 1; i < number_of_nodes; ++i){
// ...
}
Also in C++11 main() does not need to return 0;.
1
"Another probably micro optimization would be to write ++i in loops" For this case (integer or other primitive type), there is no optimization gain at all. For user-defined types, you are correct: postincrement involves a copy to be made, whereas preincrement doesn't. So prefer ++i for user-defined types, and then continue to use it for primitive data types if the choice between pre- vs post- increment doesn't matter, for code consistency.
– scottbb
Apr 25 '16 at 12:29
fully agree, but i think is good habit to use it as ++i
– Nick
Apr 25 '16 at 17:42
Agreed, hence the last part of my comment, "continue to use it for primitive data types ... for code consistency"
– scottbb
Apr 25 '16 at 18:06
add a comment |
Code looks OK.
I would suggest you to do some class instead of Edge:
//typedef pair<pair<int, int>, int> Edge; //a, b, length
struct Edge{
int a;
int b;
int length;
};
Also I suggest to have some predefined type for vector<Edge>
using EdgeContainer = vector<Edge>;
You have duplication near //find the shortest edge, you probably need Edge there
Here the_shortest is probably not initialized. Also you probably might use something from <algorithm> (but I will do it in same way as you).
//find the shortest edge
pair<pair<int, int>, int> the_shortest;
the_shortest = edges_with_lengths.front();
for(auto i: edges_with_lengths){
if(the_shortest.second > i.second)
the_shortest = i;
}
Another probably micro optimization would be to write ++i in loops:
//for (int i = 1; i < number_of_nodes; i++)
for (int i = 1; i < number_of_nodes; ++i){
// ...
}
Also in C++11 main() does not need to return 0;.
1
"Another probably micro optimization would be to write ++i in loops" For this case (integer or other primitive type), there is no optimization gain at all. For user-defined types, you are correct: postincrement involves a copy to be made, whereas preincrement doesn't. So prefer ++i for user-defined types, and then continue to use it for primitive data types if the choice between pre- vs post- increment doesn't matter, for code consistency.
– scottbb
Apr 25 '16 at 12:29
fully agree, but i think is good habit to use it as ++i
– Nick
Apr 25 '16 at 17:42
Agreed, hence the last part of my comment, "continue to use it for primitive data types ... for code consistency"
– scottbb
Apr 25 '16 at 18:06
add a comment |
Code looks OK.
I would suggest you to do some class instead of Edge:
//typedef pair<pair<int, int>, int> Edge; //a, b, length
struct Edge{
int a;
int b;
int length;
};
Also I suggest to have some predefined type for vector<Edge>
using EdgeContainer = vector<Edge>;
You have duplication near //find the shortest edge, you probably need Edge there
Here the_shortest is probably not initialized. Also you probably might use something from <algorithm> (but I will do it in same way as you).
//find the shortest edge
pair<pair<int, int>, int> the_shortest;
the_shortest = edges_with_lengths.front();
for(auto i: edges_with_lengths){
if(the_shortest.second > i.second)
the_shortest = i;
}
Another probably micro optimization would be to write ++i in loops:
//for (int i = 1; i < number_of_nodes; i++)
for (int i = 1; i < number_of_nodes; ++i){
// ...
}
Also in C++11 main() does not need to return 0;.
Code looks OK.
I would suggest you to do some class instead of Edge:
//typedef pair<pair<int, int>, int> Edge; //a, b, length
struct Edge{
int a;
int b;
int length;
};
Also I suggest to have some predefined type for vector<Edge>
using EdgeContainer = vector<Edge>;
You have duplication near //find the shortest edge, you probably need Edge there
Here the_shortest is probably not initialized. Also you probably might use something from <algorithm> (but I will do it in same way as you).
//find the shortest edge
pair<pair<int, int>, int> the_shortest;
the_shortest = edges_with_lengths.front();
for(auto i: edges_with_lengths){
if(the_shortest.second > i.second)
the_shortest = i;
}
Another probably micro optimization would be to write ++i in loops:
//for (int i = 1; i < number_of_nodes; i++)
for (int i = 1; i < number_of_nodes; ++i){
// ...
}
Also in C++11 main() does not need to return 0;.
answered Apr 25 '16 at 11:31
Nick
667413
667413
1
"Another probably micro optimization would be to write ++i in loops" For this case (integer or other primitive type), there is no optimization gain at all. For user-defined types, you are correct: postincrement involves a copy to be made, whereas preincrement doesn't. So prefer ++i for user-defined types, and then continue to use it for primitive data types if the choice between pre- vs post- increment doesn't matter, for code consistency.
– scottbb
Apr 25 '16 at 12:29
fully agree, but i think is good habit to use it as ++i
– Nick
Apr 25 '16 at 17:42
Agreed, hence the last part of my comment, "continue to use it for primitive data types ... for code consistency"
– scottbb
Apr 25 '16 at 18:06
add a comment |
1
"Another probably micro optimization would be to write ++i in loops" For this case (integer or other primitive type), there is no optimization gain at all. For user-defined types, you are correct: postincrement involves a copy to be made, whereas preincrement doesn't. So prefer ++i for user-defined types, and then continue to use it for primitive data types if the choice between pre- vs post- increment doesn't matter, for code consistency.
– scottbb
Apr 25 '16 at 12:29
fully agree, but i think is good habit to use it as ++i
– Nick
Apr 25 '16 at 17:42
Agreed, hence the last part of my comment, "continue to use it for primitive data types ... for code consistency"
– scottbb
Apr 25 '16 at 18:06
1
1
"Another probably micro optimization would be to write ++i in loops" For this case (integer or other primitive type), there is no optimization gain at all. For user-defined types, you are correct: postincrement involves a copy to be made, whereas preincrement doesn't. So prefer ++i for user-defined types, and then continue to use it for primitive data types if the choice between pre- vs post- increment doesn't matter, for code consistency.
– scottbb
Apr 25 '16 at 12:29
"Another probably micro optimization would be to write ++i in loops" For this case (integer or other primitive type), there is no optimization gain at all. For user-defined types, you are correct: postincrement involves a copy to be made, whereas preincrement doesn't. So prefer ++i for user-defined types, and then continue to use it for primitive data types if the choice between pre- vs post- increment doesn't matter, for code consistency.
– scottbb
Apr 25 '16 at 12:29
fully agree, but i think is good habit to use it as ++i
– Nick
Apr 25 '16 at 17:42
fully agree, but i think is good habit to use it as ++i
– Nick
Apr 25 '16 at 17:42
Agreed, hence the last part of my comment, "continue to use it for primitive data types ... for code consistency"
– scottbb
Apr 25 '16 at 18:06
Agreed, hence the last part of my comment, "continue to use it for primitive data types ... for code consistency"
– scottbb
Apr 25 '16 at 18:06
add a comment |
you have not used priority queue so performance is bad
New contributor
sukumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
you have not used priority queue so performance is bad
New contributor
sukumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
you have not used priority queue so performance is bad
New contributor
sukumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
you have not used priority queue so performance is bad
New contributor
sukumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
sukumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
answered 2 mins ago
sukumar
1
1
New contributor
sukumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
sukumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
sukumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f126617%2fimplementation-of-prims-algorithm-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown