【问题标题】:Adding of a edge in a graph using adjaceny-list in c++在 C++ 中使用邻接列表在图中添加边
【发布时间】:2018-04-15 20:51:43
【问题描述】:

这是我定义图表的方式,它特定于我正在处理的问题。

    class Vertex;

    Class Edge
    {
        Vertex *org;
        Vertex *dest;
        int traverse_time;
    };
    struct Vertex{
        int id;
        vector<Edge> edges;
        int weight;
    };
    struct Graph{
        vector<Vertex> vertices;
    };

这就是我添加顶点的方式

Graph* g1=new Graph; Vertex* newvertex = addVertex(0); graph1->vertices.push_back(*newvertex);

添加顶点功能可以正常工作,但如果您需要,仍然可以

Vertex* addVertex(int id){
Vertex*newVertex = new Vertex;
newVertex->id=id;
newVertex->weight=0;
return newVertex;}

当我尝试向这些顶点添加边时遇到问题。这就是我一直在做的事情

org=&(g1->vertices[0]);
dest=&(g1->vertices[1]);
Edge* newedge=addRoad(org,dest,1);
org->edges.push_back(*newedge);
dest->edges.push_back(*newedge);

addEdge函数定义如下:

Edge* addedge(Vertex* j_id1,Vertex* j_id2,int t)
{
    Edge *newedge =new Edge;
    newedge->org=j_id1;
    newedge->dest=j_id2;
    newedge->traverse_time=t;
    return newedge;
}

函数在org-&gt;edges.push_back(*newedge);之前停止工作

【问题讨论】:

  • Vertex* new = addVertex(0); 不应该编译。另外,停止工作是什么意思?
  • 我的错,那是Vertex *newvertex=addVertex(0); 尝试插入边时程序退出。
  • 有报错吗?
  • 不,没有给出错误。当我尝试向我的图形添加边时,exe 文件停止工作。我注释掉了添加边的部分,程序的其余部分工作正常。
  • 这行是问题org-&gt;edges.push_back(*newedge);我猜

标签: c++ vector graph adjacency-list


【解决方案1】:

在使用指向向量元素的指针时必须小心,因为当向量被调整大小时(当它没有剩余空间时调用push_back),并不能保证每个元素仍将占用相同的内存地址.

改为使用索引

struct Edge
{
    unsigned A, B;  // indices
    int weight;

    Edge(unsigned a, unsigned b, int w) : A(a), B(b), weight(w) {}
};
struct Vertex
{
    int id, weight;
    vector<unsigned> edges;  // edge indices

    Vertex(int i, int w) : id(i), weight(w) {}
};

struct Graph
{
    vector<Vertex> vertices;
    vector<Edge>   edges;   // use a vector for edges too for EZ deallocation

    // make the relevant functions members

    void addVertex(int id)
    {
        // in-place constructor
        vertices.emplace_back(id, 0);
    }
    bool addEdge(unsigned v1, unsigned v2, int t)
    { 
        // check if indices are valid
        if (v1 >= vertices.size() && v2 >= vertices.size())
            return false;

        unsigned newindex = edges.size();  // index of new edge
        edges.emplace_back(v1, v2, t);

        // add this edge's index to endpoints
        vertices[v1].edges.push_back(newindex);
        vertices[v2].edges.push_back(newindex);

        return true;
    }
};

许多其他可能的改进,但这至少应该解决内存访问问题。

【讨论】:

    【解决方案2】:

    Edge 从类更改为结构,或将其属性设为公共,类具有标准私有成员,而结构具有公共成员。

    【讨论】:

    • 我将Edge 更改为struct 但当我尝试添加边缘时.exe 仍然停止工作
    • 尝试从命令行启动可执行文件,它将保持打开状态并显示错误
    • 这是我得到的munmap_chunk(): invalid pointer: 0x000055a75ac0c3e8 *** Aborted (core dumped)
    【解决方案3】:

    您的设计有几个缺陷,为什么您将 Edge 定义为:

    Class Edge
    {
        Vertex *org;
        Vertex *dest;
        int traverse_time;
    };
    

    如果将其邻居定义为邻接列表,则顶点之间的关系应该是明确的,即:

    Class Cost
    {
        int traverse_time;
    };
    
    struct Vertex{
        int id;
        map<shared_ptr<Vertex>, Cost> neighbours;
        int weight;
    };
    

    接下来,当您在解决方案中添加顶点时,您会编写:

    Edge* newedge=addRoad(org,dest,1);
    org->edges.push_back(*newedge);
    dest->edges.push_back(*newedge);
    

    这对 dest 顶点没有多大意义,因为您的边缘来自 orig -> dest。

    【讨论】:

    • 好的,但这是一个无向加权图。所以我在 org 和 dest 中都添加了边。这种方法正确吗?
    • adjacency-list 的全部意义在于它创建了关系,您不必创建 Edge 类。它是无向的这一事实不会改变所说的和加权的,这意味着它只是在边缘之间有一些成本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2022-01-16
    相关资源
    最近更新 更多