链式前向星(最通俗易懂的讲解)

链式前向新:用于存储图的 边集 数组

前言

当我们存储图的时候,往往会使用 邻接矩阵 或是 邻接表。

邻接矩阵 好写,但太浪费空间,节点一多就存不下;

邻接表 效率高,但涉及指 ,不好写容易出错;用 vector 又可能超时。

链式前向星 就是一个相对中庸的存储方式,虽然说,链式前向星 使用并不广泛,但在需要使用复杂 邻接表 时,这就是一个较好的选择。

链式前向星 其实就是 静态建立的邻接表,时间复杂度为O(m),空间复杂度也为O(m)。


思想

对于下图:

图1

输入为:

5 7

1 2 3

2 3 1

1 3 4

1 5 3

4 1 5

4 5 1

3 4 2

我们将起点都是 from 的边串在一起,用 head[from] 存储头节点(见图2,下图为最终形式)

图2

具体插入操作与链表相似 (见图3)

图3


代码与运行结果

里有注释,慢慢理解

cpp 复制代码
#include <iostream>
#include <cstring>

using namespace std;

const int N = 2e2 + 5, M = 1e3 + 5;

int n, m, cnt; //n个点,m条边
struct Edge {
	int to, value, next;
	//终点,边权,同起点的上一条边的编号
} edge[M]; //边集
int head[N]; //head[i] 表示以 i 为起点的第一条边在边集数组的位置(编号)

void add_edge(int from, int to, int value) { //u起点,v终点,w边权
	edge[++ cnt] = {to, value, head[from]}, head[from] = cnt;
	// 赋终点权值 并且将新的节点赋在头上	更新头
}

int main() {
	cin >> n >> m;

	/* 初始化 */
	cnt = 0;
	memset(head, -1, sizeof head);

	/* 加边 */
	for (int i = 1; i <= m; i ++) { //输入m条边
		int a, b, c;
		cin >> a >> b >> c;
		add_edge(a, b, c);
	}

	/* 遍历 */
	for (int i = 1; i <= n; i ++) {
		cout << ">" << i << "\n";
		bool hase = false;
		for (int j = head[i]; j != -1; j = edge[j].next) //遍历以i为起点的边
			cout << i << " " << edge[j].to << " " << edge[j].value << "\n", hase = true;
		if (!hase)
			cout << "nothing\n"; //第i个节点没有出去的边
	}
	return 0;
}
/*
5 7
1 2 3
2 3 1
1 3 4
1 5 3
4 1 5
4 5 1
3 4 2
*/

可以注意到 head 的初始值为 -1

这使得 head[i] 中第一个边的 next 为 -1,这正作为链的结尾(见图3

所以当 访问指针 ( j ) 为 -1 时,就代表访问结束了

运行结果参考

图4

(从 图2~4 和 代码中,我们都可以发现 链式前向星 是按输入倒着存的)


结语

个人觉得 链式前向星 和 邻接表 是几乎一样的,只不过 前者 是静态的,后者 是动态的

相关推荐
yuanbenshidiaos1 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习1 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA1 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo1 小时前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc1 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
游是水里的游2 小时前
【算法day20】回溯:子集与全排列问题
算法
yoyobravery3 小时前
c语言大一期末复习
c语言·开发语言·算法
Jiude3 小时前
算法题题解记录——双变量问题的 “枚举右,维护左”
python·算法·面试
被AI抢饭碗的人3 小时前
算法题(13):异或变换
算法
nuyoah♂4 小时前
DAY36|动态规划Part04|LeetCode:1049. 最后一块石头的重量 II、494. 目标和、474.一和零
算法·leetcode·动态规划