笔者写下这篇文章的契机是,前两天在上机课用纯链式存储写题,累的够呛。于是痛定思痛,在此梳理一遍链式前向星,也希望能给有同样困扰的同学们提供一点帮助。
在进入正题之前,我们先用邻接矩阵和邻接表引入。
-
邻接矩阵表示图

邻接矩阵的存储原则为:
第i个结点指向第j个结点。则将矩阵中matrix[i][j]=w,w为边的权值
可以很好的将链式存储结构转化为一个矩阵来存储。缺点是浪费空间。 -
邻接表表示图

邻接表常用vector,但是vector的隐藏常数太大,空间复杂度高。
由此我们在邻接表的基础上引入了链式前向星 -
链式前向星

存储结构
#define MaxSize 100
typedef struct Edge {
int to, w, next;
} Edge;
int tot;
int head[MaxSize];
Edge edge[MaxSize];
to为被指向的当前结点编号。w为权值,next被定义为,与上一元素父节点相同的兄弟结点。(比如图中,1->2 1->4 1->3;则结点2的next=4;结点4的next=3)
head[i]为父结点i指向的第一个子结点。(head[i]只要求互不相同即可。)
遍历函数
for (int i = 1; i <= MaxSize; i++) { //从1开始
for (int j = head[i]; j != -1; j = edge[j].next;) {
printf("结点%d->结点%d的权值为%d", i, edge[j].to; edge[j].w);
}
}
拿i=1的遍历举例



加边函数
特别的是,与普遍链表不同,在链式前向星中,是在头部插入新结点,而非NULL处
void add_edge(int u, int v, int w) { //u为起点,v为终点,w为权值
edge[tot].to = v; //tot为空结点指针
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;//tot为任一个未被使用的空节点指针。
}



注意:此时tot不一定为其指向结点的to值。
作者因上机课用纯链式存储写题困难,故而梳理链式前向星。文章先通过邻接矩阵和邻接表引入,指出邻接矩阵浪费空间、邻接表空间复杂度高的缺点,进而介绍链式前向星的存储结构、遍历函数和加边函数,还提及它在头部插入新结点的特点。

被折叠的 条评论
为什么被折叠?



