链表节点 A 的编号是 0, 指向了 编号为 2 的 C,还指向了 编号为 1 的 B。
因此我们可以通过 NodeTable 的 adj[0] 找到 A 节点所指向的节点 B 和 节点 C。
C语言描述的一幅邻接链表, 无向图和有向图都可以表示
#include <stdio.h>
#include <stdlib.h>
typedef int bool;
#define false 0;
#define true 1;
typedef struct Edge {
int dest;
double weight;
struct Edge * link;
} Edge;
typedef struct LinkListMap {
int n;
int * data;
struct Edge ** adj;
} LinkListMap;
// 初始化有 n 个节点的图
void InitMap(struct LinkListMap * map, int n) {
map->n = n;
map->data = (int*)malloc(n*sizeof(int));
map->adj = (struct Edge**)malloc(n*sizeof(struct Edge*));
for(int i=0; i<n; i++) {
map->adj[i] = NULL;
}
}
void DestroyMap(struct LinkListMap * map) {
free(map->data);
for(int i=0; i<map->n; i++) {
struct Edge* nex;
for (struct Edge* e=map->adj[i]; e!=NULL; e=nex) {
nex = e->link;
free(e);
}
}
free(map->adj);
}
struct Edge * AddEdge(struct LinkListMap * map,
unsigned int source/*0~n-1*/,
unsigned int dest/*0~n-1*/,
double weight)
{
if(map->n < source || map->n < dest || map == NULL) return NULL;
struct Edge * edge = (struct Edge *)malloc(sizeof(struct Edge));
edge->dest = dest;
edge->weight = weight;
struct Edge * pre = map->adj[source];
struct Edge * nex = pre;
// 查找插入位置
while (nex != NULL) {
if(dest < nex->dest)
break;
else if(dest == pre->dest)
return NULL;
pre = nex;
nex = nex->link;
}
// 插入新的边为第一条边
if (pre == NULL || dest < pre->dest) {
map->adj[source] = edge;
} else {
pre->link = edge;
}
edge->link = nex;
return edge;
}
struct Edge * GetEdge(struct LinkListMap * map,
unsigned int source/*0~n-1*/,
unsigned int dest/*0~n-1*/)
{
if(map->n < source || map->n < dest || map == NULL) return NULL;
struct Edge * edge = map->adj[source];
while(edge->dest < dest && edge->link != NULL) {
edge = edge->link;
}
if(edge->dest != dest) return NULL; // 不存在从 source 到 dest 这条边
return edge;
}
void print(struct LinkListMap * map) {
for (int i=0; i<map->n; i++) {
for (struct Edge * e=map->adj[i]; e!=NULL; e=e->link) {
printf("from: %d, to: %d, weight: %lf\n", i, e->dest, e->weight); }
}
}
int main(void)
{
LinkListMap map;
InitMap(&map, 3);
// 图,起点,终点,权值
AddEdge(&map, 0, 2, 3.0);
AddEdge(&map, 0, 1, 3.0);
AddEdge(&map, 1, 0, 4.0);
AddEdge(&map, 1, 3, 4.0);
AddEdge(&map, 3, 1, 5.0);
print(&map);
printf("Weight of edge 0 to 2 is %lf\n", GetEdge(&map, 0, 1)->weight);
DestroyMap(&map);
return 0;
}