[英]Add edge to a directed graph (Adjacency list) implemented using Linked List in C++
我有搜索,但找不到与我的情况有关的任何内容。
我只想使用链表在c ++中实现图形。 我的结构如下:
class Vertex
{
public:
Vertex(std::string name = "none");
private:
std::string name;
Edge *edges;
Vertex *next;
Runnable *runnables;
};
class Edge
{
public:
Edge();
private:
Vertex *connectsTo;
Edge *next;
};
class TaskGraph{
public:
TaskGraph();
private:
Vertex *head;
};
我有一种方法可以将顶点添加到图中的void addVertex(TaskGraph * taskGraph,const std :: string&);
这种方法效果很好,因为我可以打印出图中的所有顶点。 另一方面,要添加有向边,我做了这样的事情:
void MyGraph::addEdge(TaskGraph* taskGraph, const string& src, const string& dest){
//get to the source vertex: this is ok
//get to the destination vertex: this is also ok
//add edge : the problem is here // s is source vertex while d is destination vertex.
Edge *e = new Edge;
e->connectsTo = d;
if(s->edges == 0){
s->edges = e;
}else{
s->edges->next = e;
}
}
加入说5个边后,只有两个实际上添加(即第一和列表的边缘,其他人都被替换)。 我发现这是因为以下这一行:“ s-> edges-> next = e; ”,但无法弄清楚如何正确实现它。 请帮忙!!!
谢谢
您正在打破名单。 当您插入边缘时。 因此,您的第一种情况始终有效。 您只需添加e就可以了。
另一种情况是将e添加为第二条边,但会放宽先前添加的所有其他边。
试试这个代替:
//add edge : the problem is here
Edge *e = new Edge;
e->connectsTo = d;
//If there is already a list node pointing to in s->edges...
if(s->edges != 0){
//Then apply the existing list to the back of the new node.
// this add the exiting edges to the new one so you do not break the list.
e->next = s->edges;
}
//Apply e as the head of the list (pointing to it via s->edges).
s->edges = e;
此算法将新边缘添加到列表的最前面,因此它们将以与您添加它们的顺序相反的顺序出现。
要使边缘保持与插入时相同的顺序,您可以按照以下建议进行循环或为列表中的最后一条边缘添加尾指针。
最重要的是,您应该了解自己在做什么错。
你开始
S->edges->NULL
您添加了一条边缘E1
S->edges->E1.next->NULL
现在,您添加了第二条边E2并:
S->edges->E1.next->E2.next->NULL
到现在为止还挺好。 但是,当您添加E3时,会发生什么情况:
S->edges->E1.next->E3.next->NULL lost link to E2.next->NULL
这就是为什么无论您尝试添加多少条边,列表中都只有2条边的原因。 这也称为内存泄漏,因为您丢失了对E2实例的所有引用,并且无法清理这些对象。
好的,这就是示例实现,下面的评论中其他人在谈论如何将列表保持与添加的边缘相同的顺序。 所以E1是第一个E2第二个,依此类推...
class Vertex
{
public:
Vertex(std::string name = "none");
private:
std::string name;
Edge *edges;
Edge *lastEdge; // this will keep track of the last edge in the list.
// with this pointer you avoid having to loop through all
// the edges every time to add to the end.
Vertex *next;
Runnable *runnables;
};
void MyGraph::addEdge(TaskGraph* taskGraph, const string& src, const string& dest)
{
//get to the source vertex: this is ok
//get to the destination vertex: this is also ok
//add edge : the problem is here // s is source vertex while d is destination vertex.
Edge *e = new Edge;
e->connectsTo = d;
if(s->edges == 0)
{
s->edges = e;
// set the last edge to point to the first item.
s->lastEdge = e;
}
else
{
// In this case the logic is simple you already know that
// the list is not empty and that lastEdge is pointing at the
// last edge in the list so just make the current lastEdge
// point to the new edge. This will grow your list with e at
// the end.
// Then update lastEdge to point to the new edge you just added.
// so that is it pointing to the end of the list again.
s->lastEdge->next = e;
s->lastEdge = e;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.