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

news2024/10/5 1:38:32

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

前言

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

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

邻接表 效率高,但涉及指 ,不好写容易出错;用 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


代码与运行结果

里有注释,慢慢理解

#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 和 代码中,我们都可以发现 链式前向星 是按输入倒着存的)


结语

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2189057.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大语言模型入门(三)——提示词编写注意事项

一、提示词编写原则 提示词的编写应当遵循两个原则&#xff0c; 一个是指令必须清晰且具体&#xff0c;另一个是应当给模型充足的时间去思考。首先&#xff0c;你的指令足够清晰和具体&#xff0c;才能让大模型明确你需要它执行的任务&#xff0c;从而降低我们得到无关或者不正…

C# 入坑JAVA 潜规则 注解 列表 listMch,该列表存储了一个映射(Map)的集合 等 入门系列3

java注解 好像和C# 特性 差不多 Data Builder NoArgsConstructor AllArgsConstructor 在Java中&#xff0c;Data、Builder、NoArgsConstructor和AllArgsConstructor是Lombok库提供的注解&#xff0c;它们用于简化Java对象的创建和处理。Lombok是一个流行的Java库&#xff0c;…

java部分总结

一、Java语言发展简史 Java 语言源于 1991 年 4 月&#xff0c; Sun 公司 James Gosling 博士 领导的绿色计划 (Green Project) 开始启动&#xff0c;此计划最 初的目标是开发一种能够在各种消费性电子产品( 如机顶盒、冰箱、收音机等 ) 上运行的程序架构。这个就是 Jav…

基于Pulid-Flux一致性换脸

Pulid-Flux 简介 Pulid-Flux是风格一致性保持和迁移组件&#xff0c;是字节Pulid团队继SDXL的Pulid版本沉淀基础上再次出发布的PuLID-FLUX-v0.9.0 Flux版本风格一致性组件。能够提供了一个无需调整的身份ID一致性和定制化解决方案&#xff0c;能够被应用于风格一致性保持领域包…

如何写出更牛的验证激励

前言 芯片验证是为了发现芯片中的错误而执行的过程&#xff0c;它是一个破坏性的过程。完备的验证激励可以更有效地发现芯片错误&#xff0c;进而缩短验证周期。合格的验证激励必须能产生所有可能的验证场景(完备性)&#xff0c;包括合法和非法的场景&#xff0c;并保持最大的…

Stable Diffusion绘画 | 来训练属于自己的模型:炼丹启动

经过前面几轮辛苦的准备工作之后&#xff0c;现在开始进入终篇的炼丹环节。 在「上传素材」页面&#xff0c;点击「开始训练」&#xff1a; 可以在「查看进度-进度」中&#xff0c;查看模型训练的整体进度&#xff1a; 求助&#xff01;&#xff01;&#xff01;操作「开始训练…

date:10.4(Content:Mr.Peng)( C language practice)

void reverse(char* p, int len) {char* left p;char* right p len - 2;while (left < right){char* temp left;*left *right;//当*left*right后&#xff0c;*temp已经被改为f了*right *temp;//你再*temp赋值给*right时&#xff0c;已经没用了left;right--;}}int main…

前端学习第三天笔记 JavaScript JavaScript的引入 数据类型 运算符 条件语句 字符串

这里写自定义目录标题 JavaScriptJavaScript引入到文件嵌入到HTML文件中引入本地独立js文件引入网络来源文件 JavaScript的注释方式嵌入在HTML文件中的注释JavaScript的输出方式数据类型原始类型&#xff08;基础类型&#xff09;合成类型&#xff08;复合类型&#xff09; 运算…

Github优质项目推荐-第二期

文章目录 Github优质项目推荐 - 第二期一、【hello-algo】&#xff0c;96.1k stars - 算法与数据结构动画图解二、【tabby】&#xff0c;58.6k stars - ssh工具三、【mem0】&#xff0c;22.1k stars - 大模型长期记忆四、【HivisionIDPhotos】&#xff0c;10.6k stars - AI证件…

多智能体协作强化学习中的知识共享

本文提出了一种名为谨慎乐观知识共享&#xff08;CONS&#xff09;的新方法&#xff0c;用于解决合作多智能体强化学习&#xff08;MARL&#xff09;中的知识共享问题。针对传统的行动建议方法可能导致团队探索受阻的情况&#xff0c;即经验丰富的智能体会分享其知识而较不成熟…

【C++算法】10.滑动窗口_长度最小的子数组

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; 209. 长度最小的子数组 题目描述&#xff1a; 解法 解法一&#xff1a;暴力求解&#xff08;会超时&#xff09; 暴力枚举出所有子数组的和。 查找子数组n2&#xff0…

03:(寄存器开发)OLED的简单使用

OLED的简单使用 将江科大的标准库开发OLED的代码进行移植&#xff0c;修改的部分代码如下&#xff1a; /*引脚配置*/ //#define OLED_W_SCL(x) GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x)) //#define OLED_W_SDA(x) GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))…

mybatis-plus使用总结

基本使用 mybatis-plus依赖 <!-- mybatis-plus开始 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.7</version></dependency><dependency>&l…

D27【 python 接口自动化学习】- python 基础之判断与循环

day27 判断和循环中常见错误 学习日期&#xff1a;20241004 学习目标&#xff1a;判断与循环&#xfe63;-38 避坑指南&#xff1a;判断和循环中的常见错误 学习笔记&#xff1a; 循环过程中改变遍历次数 遍历中修改列表导致误操作 循环嵌套中的缩进导致运行语句有差别 总结…

17 链表——21. 合并两个有序链表 ★

17 链表 21. 合并两个有序链表 将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4] 算法设计: 合并两个有序链表,并保持有序性,可以采用迭代法和递归法两种…

小白必看web专题!渗透测试还是src?

大家好&#xff0c;我是Dest1ny&#xff01; 今天是回答问题的&#xff0c;有小伙伴私信我&#xff1a; 渗透测试还是src&#xff1f; 今天回答一下&#xff01; 渗透测试&#xff08;Penetration Testing&#xff09;&#xff1a; 渗透测试是一种模拟真实攻击者的技术手段&…

Vue3+TS项目 - ref和useTemplateRef获取组件实例

在Vue2中&#xff0c;子组件使用的是选项式 API &#xff0c;被引用的组件实例和该子组件的 this 完全一致&#xff0c;这意味着父组件对子组件的每一个属性和方法都有完全的访问权。这使得在父组件和子组件之间创建紧密耦合的实现细节变得很容易&#xff0c;当然也因此&#x…

java相关新技术

Java作为一种广泛应用的编程语言&#xff0c;其新技术层出不穷&#xff0c;为开发者提供了更多的工具和框架来构建高效、可扩展的应用程序。以下是一些当前比较热门的Java新技术 Java 17及更高版本&#xff1a; Java平台持续更新&#xff0c;每个新版本都带来了性能改进和新特…

C++学习笔记之类对象(一)

C学习笔记之类&对象&#xff08;一&#xff09; https://www.runoob.com/cplusplus/cpp-classes-objects.html 类是C的核心特性&#xff0c;为用户自定义的数据类型&#xff0c;可以在其中放入数据和函数作为成员&#xff0c;并且以此为模板&#xff0c;创建多个对象个体进…