[英]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.