C语言中邻接表图的实现
我读了一段代码,它实现了一个带有邻接列表的图。但是我对加法函数非常困惑 在下面代码的函数中,当使用数组[src].head为newNode->next赋值时。这意味着newNode的下一个节点是C语言中邻接表图的实现,c,graph,adjacency-list,C,Graph,Adjacency List,我读了一段代码,它实现了一个带有邻接列表的图。但是我对加法函数非常困惑 在下面代码的函数中,当使用数组[src].head为newNode->next赋值时。这意味着newNode的下一个节点是数组[src].head。但是在语句“graph->array[src].head=newNode;”之后,当我们测试结果时,顺序正好相反。有人能给我解释一下吗?谢谢 #include <stdio.h> #include <stdlib.h> // A structure
数组[src].head。但是在语句“graph->array[src].head=newNode;”之后,当我们测试结果时,顺序正好相反。有人能给我解释一下吗?谢谢
#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;
}
#包括
#包括
//表示邻接列表节点的结构
结构AdjListNode
{
int dest;
结构AdjListNode*下一步;
};
//表示邻接列表的结构
结构调整列表
{
结构AdjListNode*头;
};
//表示图形的结构。图表
//是邻接列表的数组。
//数组的大小为V(顶点数
//(在图表中)
结构图
{
INTV;
结构调整列表*数组;
};
//用于创建新邻接列表节点的实用程序函数
结构AdjListNode*newAdjListNode(int dest)
{
结构AdjListNode*新节点=
(struct AdjListNode*)malloc(sizeof(struct AdjListNode));
newNode->dest=dest;
newNode->next=NULL;
返回newNode;
}
//创建V顶点图的实用函数
结构图*createGraph(int V)
{
结构图*图=
(结构图*)malloc(sizeof(结构图));
图形->V=V;
//创建邻接列表数组。的大小
//数组将为V
图形->数组=
(结构调整列表*)malloc(V*sizeof(结构调整列表));
//通过将每个邻接列表初始化为空
//使头部为空
int i;
对于(i=0;i数组[i]。head=NULL;
返回图;
}
//将边添加到无向图
void addEdge(结构图*图,int src,int dest)
{
//将边从src添加到dest。将创建一个新节点
//添加到src的邻接列表中。节点
//是在开头添加的
结构AdjListNode*newNode=newAdjListNode(dest);
newNode->next=graph->array[src].head;
图形->数组[src].head=newNode;
//因为图形是无向的,所以从
//目的地至src
newNode=newAdjListNode(src);
新建节点->下一步=图形->数组[dest].head;
图形->数组[dest].head=newNode;
}
//打印邻接列表的实用函数
//图的表示
void printGraph(结构图*图形)
{
INTV;
对于(v=0;vv;++v)
{
结构AdjListNode*pCrawl=graph->array[v].head;
printf(“\n顶点%d\n头的邻接列表”,v);
while(pCrawl)
{
printf(“->%d”,pCrawl->dest);
pCrawl=pCrawl->next;
}
printf(“\n”);
}
}
//用于测试上述功能的驱动程序
int main()
{
//创建上图中给出的图表
int V=5;
结构图*Graph=createGraph(V);
加法(图,0,1);
加法(图,0,4);
附录(图1,2);
附录(图1,3);
附录(图1,4);
附录(图2,3);
附录(图3、4);
//打印上图的邻接列表表示形式
印刷图形;
返回0;
}
在以下代码的功能中,当启用newNode->next
时
分配了数组[src]。头。这意味着
newNode
是array[src]。head
。但是在声明之后
graph->array[src].head=newNode代码>,顺序是相反的
当我们测试结果时。有人能给我解释一下吗?谢谢
#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;
}
这是正确的。函数addEdge
将在列表的开头插入新节点,您已经从测试输出中确认了这一点
这一行:
newNode->next = graph->array[dest].head;
使新节点的next
指针指向当前列表的开头(在更新列表之前)
那么这一行:
graph->array[dest].head = newNode;
更新列表的开头以指向刚添加的新节点
现在,列表如下所示:
[head == new-node] -> [... state of list before addEdge was called ...]
在graph->array[dest]之后不是head==[new node]而不是head->[new node],head=newNode??如果head==新节点,我们如何将图形->数组[]。head链接到我们添加的所有节点??我不理解你的问题。此函数所做的只是将新节点添加到列表的开头,指定从src到dest的边。然后以类似的方式从dest向src添加一条边。我的意思是,如果我们不断更新head指针,那么如果我们想要打印列表,我们如何获得原始指针?因为当添加所有边时,头部点是列表每行中的最后一个节点。当添加所有边时,头部点是添加的最后一个节点。。。这是列表中的第一个节点。在为特定src边添加任何边之前,没有边,因此原始头指针为空。我不知道你为什么关心指针的变化。您的所有数据都在该列表中。您可以遍历列表(如printGraph
中的内部循环)以访问所有数据。