Prim的向量<vector <int>&gt;算法导致SegFault

时间:2017-12-10 04:55:35

标签: c++ vector segmentation-fault prims-algorithm

我有以下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算法在图表中找到最小生成树的边缘。

2 个答案:

答案 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在哪里定义?您似乎在迭代keymstSet。确保它们的大小相同或更好,使用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循环不是必需的,因为keymstSet的构造函数使用构造函数的第二个参数中指定的值初始化向量(或者在vector<bool>,值设置为false)。