我有以下3个功能:
int minKey(vector<int> key, vector<bool> mstSet){
int min = INT_MAX;
int min_index;
for (int i = 0; i<elements2D.size(); i++){
if (mstSet[i] == false && key[i] < min){
min = key[i];
min_index = i;
}
}
return min_index;
}
int printMST(vector<int> parent, int n, vector<vector<int>> graph){
cout << "edges: " << endl;
for (int i = 1; i<graph.size(); i++){
cout << parent[i] << " " << i << endl;
}
}
void primMST(vector<vector<int>> graph){
vector<int> parent;
parent.reserve(graph.size());
vector<int> key;
key.reserve(graph.size());
vector<bool> mstSet;
mstSet.reserve(graph.size());
for (int i = 0; i<graph.size(); i++){
key[i] = INT_MAX;
mstSet[i] = false;
}
key[0] = 0;
parent[0] = -1;
for (int count = 0; count<graph.size()-1; count++){
int u = minKey(key, mstSet);
mstSet[u] = true;
for (int v = 0; v < graph.size(); v++){
if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v]){
parent[v] = u;
key[v] = graph[u][v];
}
}
}
printMST(parent, graph.size(), graph);
}
在我的主要功能中,我称之为:
primMST(elements2D); //elements2D is my adjacency matrix
然而,它不断返回分段错误。通过使用调试,我已经确定了发生这种情况的地方,但我不确定如何纠正这种情况。
所以基本上,当我说:
时,我发现了int u = minKey(key, mstSet)
导致段错误。所以我跟着它进入函数,我发现key [i]不起作用。有关它的东西不断输出我的结果作为段错误。如果有人能帮我解决这个问题,那将非常感激。
一些重要信息:
elements2D如下所示:
0 2 6 0 0 0 0 3
2 0 0 0 4 0 0 1
6 0 0 0 3 0 0 2
0 0 0 0 0 0 0 0
0 4 3 0 0 0 0 0
0 0 0 0 0 0 7 0
0 0 0 0 0 7 0 0
3 1 2 0 0 0 0 0
输出应如下所示:
edges:
0 1
1 7
2 7
2 4
5 6
我想重要的是要注意我的代码试图使用Prim算法在图表中找到最小生成树的边缘。
答案 0 :(得分:1)
int minKey(vector<int> key, vector<bool> mstSet){
int minKey(vector<int> key, vector<bool> mstSet){
int min = INT_MAX;
int min_index; // NOT INITIALIZED!
for (int i = 0; i<elements2D.size(); i++){ // What is elements2D?
if (mstSet[i] == false && key[i] < min){ // What if the two vectors are different sizes?
min = key[i];
min_index = i;
}
}
return min_index;
}
我在功能中看到了几个问题。 min_index
永远不会被初始化;如果for循环没有运行,返回什么?此外,elements2D
在哪里定义?您似乎在迭代key
和mstSet
。确保它们的大小相同或更好,使用std::vector<std::pair<int, bool>>
。
std::vector
的下标运算符不执行边界检查。使用at
可以提高安全性。
答案 1 :(得分:0)
一个错误是您使用std::vector::reserve()而不是std::vector::resize()。
这段代码访问带有越界索引的向量,因为reserve()
不会创建元素。
void primMST(vector<vector<int>> graph){
vector<int> parent;
parent.reserve(graph.size());
vector<int> key;
key.reserve(graph.size());
vector<bool> mstSet;
mstSet.reserve(graph.size());
for (int i = 0; i<graph.size(); i++){
key[i] = INT_MAX; // <-- out of bounds access
mstSet[i] = false; // <-- out of bounds access
}
修复是使用std::resize()
,因为它实际上在向量中创建条目,或构造具有必需大小的向量。
void primMST(vector<vector<int>> graph){
vector<int> parent(graph.size());
vector<int> key(graph.size(), INT_MAX);
vector<bool> mstSet(graph.size());
后续for
循环不是必需的,因为key
和mstSet
的构造函数使用构造函数的第二个参数中指定的值初始化向量(或者在vector<bool>
,值设置为false
)。