【发布时间】:2019-09-07 23:28:23
【问题描述】:
我现在正在学习图,当我从在线教学资源中阅读到使用邻接列表实现图时,我对addEdge 函数感到困惑。
addEdge(graph, 0, 1) 执行时,会创建值为 1 的节点,然后将 newNode->next 赋值为 NULL 的 graph->array[0].head。之后,graph->array[0].head 被分配了newNode。然后节点 0 和 1 连接,在函数的下半部分,它会反过来。我不知道这种方法如何连接两个节点。
谁能给我解释一下?
#include <stdio.h>
#include <stdlib.h>
// A structure to represent an adjacency list node
struct AdjListNode
{
int dest;
struct AdjListNode* next;
};
// A structure to represent an adjacency list
struct AdjList
{
struct AdjListNode *head;
};
// A structure to represent a graph. A graph
// is an array of adjacency lists.
// Size of array will be V (number of vertices
// in graph)
struct Graph
{
int V;
struct AdjList* array;
};
// A utility function to create a new adjacency list node
struct AdjListNode* newAdjListNode(int dest)
{
struct AdjListNode* newNode =
(struct AdjListNode*) malloc(sizeof(struct AdjListNode));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}
// A utility function that creates a graph of V vertices
struct Graph* createGraph(int V)
{
struct Graph* graph =
(struct Graph*) malloc(sizeof(struct Graph));
graph->V = V;
// Create an array of adjacency lists. Size of
// array will be V
graph->array =
(struct AdjList*) malloc(V * sizeof(struct AdjList));
// Initialize each adjacency list as empty by
// making head as NULL
int i;
for (i = 0; i < V; ++i)
graph->array[i].head = NULL;
return graph;
}
// Adds an edge to an undirected graph
void addEdge(struct Graph* graph, int src, int dest)
{
// Add an edge from src to dest. A new node is
// added to the adjacency list of src. The node
// is added at the begining
struct AdjListNode* newNode = newAdjListNode(dest);
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
// Since graph is undirected, add an edge from
// dest to src also
newNode = newAdjListNode(src);
newNode->next = graph->array[dest].head;
graph->array[dest].head = newNode;
}
// A utility function to print the adjacency list
// representation of graph
void printGraph(struct Graph* graph)
{
int v;
for (v = 0; v < graph->V; ++v)
{
struct AdjListNode* pCrawl = graph->array[v].head;
printf("\n Adjacency list of vertex %d\n head ", v);
while (pCrawl)
{
printf("-> %d", pCrawl->dest);
pCrawl = pCrawl->next;
}
printf("\n");
}
}
// Driver program to test above functions
int main()
{
// create the graph given in above fugure
int V = 5;
struct Graph* graph = createGraph(V);
addEdge(graph, 0, 1);
addEdge(graph, 0, 4);
addEdge(graph, 1, 2);
addEdge(graph, 1, 3);
addEdge(graph, 1, 4);
addEdge(graph, 2, 3);
addEdge(graph, 3, 4);
// print the adjacency list representation of the above graph
printGraph(graph);
return 0;
}
【问题讨论】:
-
你的图是无向的,所以如果 U 连接到 V,那么还有一个从 V 到 U 的连接。你可以对邻接矩阵做同样的事情,你会在
adj[U][V]和adj[V][U]。还是您对保存相邻节点的链表有疑问? -
问题不清楚。您的程序是否输出意外数据?
-
程序是对的。程序不是我写的。我只是对 addEdge 函数感到困惑。
-
一条无向边 (a, b) 可以被视为一对有向边 ((a, b), (b, a))。
-
顺便说一下,这种逻辑在 C++ 中更容易实现,它为您提供了丰富的“容器类”库,这样您就不必做太多容易出错的事情“指针旋转” ...
标签: c graph representation