在本教程中,您将学习什么是邻接表。此外,您还将在C中找到邻接表的示例。
邻接列表将图表示为链表数组。
数组的索引表示一个顶点,其链接链表中的每个元素表示与该顶点形成边的其他顶点。
邻接表表示法
图及其等价的邻接列表如下所示:
邻接列表在存储方面是有效的,因为我们只需要存储边的值。对于具有数百万个顶点和边的稀疏图,这意味着节省了大量空间。
邻接表结构
最简单的邻接表需要一个存储顶点的节点数据结构和一个组织节点的图数据结构。
我们紧贴图的基本定义 - 顶点和边的集合{V,E}。为了简单起见,我们使用了一个无标记的图,而不是一个有标记的图,即顶点由它们的索引 0,1,2,3 来标识。
让我们在这里深入研究一下数据结构。
struct node
{
int vertex;
struct node* next;
};
struct Graph
{
int numVertices;
struct node** adjLists;
};
不要让 struct node** adjLists 吓到你。
我们要说的是我们想要存储一个指向 struct node* 的指针。这是因为我们不知道图有多少个顶点,所以我们不能在编译时创建一个链表数组。
C示例
// Adjascency List representation in C
#include <stdio.h>
#include <stdlib.h>
struct node {
int vertex;
struct node* next;
};
struct node* createNode(int);
struct Graph {
int numVertices;
struct node** adjLists;
};
// Create a node
struct node* createNode(int v) {
struct node* newNode = malloc(sizeof(struct node));
newNode->vertex = v;
newNode->next = NULL;
return newNode;
}
// Create a graph
struct Graph* createAGraph(int vertices) {
struct Graph* graph = malloc(sizeof(struct Graph));
graph->numVertices = vertices;
graph->adjLists = malloc(vertices * sizeof(struct node*));
int i;
for (i = 0; i < vertices; i++)
graph->adjLists[i] = NULL;
return graph;
}
// Add edge
void addEdge(struct Graph* graph, int s, int d) {
// Add edge from s to d
struct node* newNode = createNode(d);
newNode->next = graph->adjLists[s];
graph->adjLists[s] = newNode;
// Add edge from d to s
newNode = createNode(s);
newNode->next = graph->adjLists[d];
graph->adjLists[d] = newNode;
}
// Print the graph
void printGraph(struct Graph* graph) {
int v;
for (v = 0; v < graph->numVertices; v++) {
struct node* temp = graph->adjLists[v];
printf("\n Vertex %d\n: ", v);
while (temp) {
printf("%d -> ", temp->vertex);
temp = temp->next;
}
printf("\n");
}
}
int main() {
struct Graph* graph = createAGraph(4);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 0, 3);
addEdge(graph, 1, 2);
printGraph(graph);
return 0;
}
参考文档
[1]Parewa Labs Pvt. Ltd.Adjacency List[EB/OL].https://www.programiz.com/dsa/graph-adjacency-list,2020-01-01.