进阶数据结构——链式前向星

C++中邻接矩阵、邻接表、链式前向星具体用法及讲解 邻接矩阵基本没用有边的数量就用链式前向星,否则就邻接表。 阅读详情

前言

链式前向星是一种进阶的数据结构,主要用于图的存储。
我希望大家先看这个视频(蓝色字体点进去) 不然你很难理解的。
在这里插入图片描述

一、背景与定义

在图论中,图的存储方式主要有邻接矩阵和邻接表两种。邻接矩阵虽然建图简单方便,但占内存较大,节点数量稍微大点的题目就难以使用(适合稠密图);而邻接表虽然节省空间,但其指针形式难写易错,且vector形式的读取速度较慢,易导致大数据下的超时(TLE)。针对上述问题,链式前向星作为一种折中的方式应运而生。

链式前向星本质上是一种静态链表,它将数据以链表形式连接在一起。具体来说,链式前向星存储的是以每个点为起点的所有边。

二、实现思路

头节点数组:建立head[maxn]数组,其中head[id]表示以id节点为起点的第一条边的编号,即查询以该节点为起点的所有边的开始边(链表头部)。head数组一般初始化为-1,表示无边可连。
边结构体:定义一个结构体Node来存储每条边的信息,包括终点to、连在同一起点上的下一条边的编号next以及边权值v(或flag,根据具体需求而定)。

struct Node {
   
   
    int to, next, v; // 或 int to, next, flag;
};

加边函数:通过加边函数将边添加到链表中。每次添加边时,都会更新head数组和Node结构体中的next指针。

void AddEdge(int a, int b, int c) {
   
   
    node[tot].next = head[a];
    node[tot].to = b;
    node[tot].v = c; // 或 node[tot].flag = c;
    head[a] = tot++;
}

三、特点与优势

节省空间:与邻接矩阵相比,链式前向星只存储存在的边,因此更加节省空间。
快速访问:通过头节点数组可以快速访问以某个点为起点的所有边。
避免排序:与需要排序的前向星相比,链式前向星可以避免排序操作,从而节省时间。

四、遍历与应用

在遍历以某个点为起点的所有边时,可以使用以下代码:

for (int i = head[u]; ~i; i = node[i].next) {
   
   
    // 访问以u为起点的边node[i]
}

链式前向星在图论算法中有广泛应用,如最短路算法、拓扑排序、强连通分量等。特别是在处理大规模稀疏图时,链式前向星能够显著提高算法的效率。

五、注意事项

初始化:在使用链式前向星之前,需要正确初始化头节点数组和边结构体数组。
边编号:在添加边时,需要确保每条边都有一个唯一的编号(通常通过全局变量tot来管理)。
遍历顺序:由于链式前向星是逆序存储边的(即后添加的边先被遍历),因此需要注意遍历顺序是否符合题目要求。如果需要按输入顺序遍历边,可以考虑使用其他数据结构或算法来实现。

六、代码模版(c++)

#include<iostream>
#include<vector>
using namespace std;

template<typename T>
struct Edge {
   
   
	int to;
	T weight;
	int next;
};

template<class T>
class Graph {
   
   
private:
	vector<Edge<T>>m_edges;
	vector<int>m_head;
public:
	Graph(int n);
	void addEdges(int from, int to, T weight);
	void printEdges();
};

template<class T>
Graph<T>::Graph(int n){
   
   
	m_edges.clear();
	m_head.resize(n, -1);
}

template<class T>
void Graph<T>::addEdges(int from, int to, T weight){
   
   
	m_edges.push_back(Edge<T>{
   
   to, weight, m_head[from]});
	m_head[from] = (int)m_edges.size() - 1;
}

template<class T>
void Graph<T>::printEdges(){
   
   
	int n = m_head.size();
	for (int i = 0; i < n; i++) {
   
   
		cout << i << ":";
		for (int e = m_head[i]; e != -1; e = m_edges[e].next) {
   
   
			int v = m_edges[e].to;
			T w = m_edges[e].weight;
			cout << "(" << v << "," << w << ")";
		}
		cout << endl;
	}
}

int main() {
   
   
	int n, m;
	cin >> n >> m;
	Graph<int>g
图论——链式前向星(个人认为比较易懂的理解方式) 目录链式前向星概括链式前向星范例链式前向星实现完整代码样例输入样例输出 链式前向星概括 以同起点为一条链,数组head[a]存储起点a的最新录入的一条边的索引,每条边以结构体的形式存储该边信息(该边终点,权值,同起点的边中的上一条边即上一次录入的边的位置),所有边构成一个结构体数组。 很多帖子说到的是存储的是下一条边,这种理解很容易给人误导,应该是每一条边都能通过自身结构体存储的信息回溯到上一条边,所以叫前向星。 假如我们要找出一条a -> b的边,先根据head[a]找出从起点a出发的所有边里最新录 阅读详情

相关推荐

前向星(Forward Star)

前向星是以储存边的方式来存储图的数据结构。构造方法如下:读入每条边的信息,将边存放在数组中,把数组中的边按照起点顺序排序(可以使用基数排序,如下面例程),前向星就构造完了。通常用在点的数目太多,或两点之间有多条弧的时候。一般在别的数据结构不能使用的时候才考虑用前向星。除了不能直接用起点终点定位以外,前向星几乎是完美的。前向星的时间复杂度为O(m),m为边数。总体时间并不会逊色于邻接表。

Hacket_Xu的博客 2124

图的存储——链式前向星

前向星 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序,并记录下以某个点为起点的所有边在数组中的起始位置和存储长度,那么前向星就构造好了 以下图为例构造前向星: len[i]记录所有以i为起点的边在数组中的存储长度 head[i]记录以i为起点的边集在数组中的第一个存储位置 利用前向星,我们可以O(len[i])的时间找到以i为起...

Happig的博客 608

使用PyTorch设计卷积神经网络(CNN)来处理遥感图像Indian Pines数据集

使用PyTorch设计卷积神经网络(CNN)来处理遥感图像Indian Pines数据集

XAX520_1314的博客 2485

C++面向对象程序设计大作业:魔兽世界(三):开战

C++面向对象程序设计大作业:魔兽世界(三):开战问题描述问题分析代码 问题描述 问题来自于北京大学郭炜老师的C++慕课的大作业 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 … N ( N <= 20)。红魔军的司令部算作编号为0的城市,蓝魔军的司令部算作编号为N+1的城市。司令部有生命元,用于制造武士。 两军的司令部都会制造武士。武士一共有dragon 、ninja、iceman、lion、wolf 五种。每种武士都有

RedRum_1965的博客 4030

OpenIddict实战指南:在.NET Core中构建安全的OAuth 2.0与OpenID Connect服务

本文详细介绍了如何在.NET Core中使用OpenIddict框架构建安全、标准的OAuth 2.0与OpenID Connect授权服务。内容涵盖从快速搭建授权服务器、理解核心配置与授权流程,到集成用户数据库、实现完整登录授权,以及生产环境下的安全加固与部署指南,为.NET开发者提供了一套现代、可维护的认证授权解决方案。

weixin_29229989的博客 352

Label Studio保姆级教程:从零搭建医疗影像标注平台(DICOM格式支持)

本文提供基于Label Studio从零搭建医疗影像标注平台的保姆级教程。针对DICOM格式支持,详细阐述了环境部署、DICOM深度集成与预处理、团队协作权限管理以及质量审核闭环等核心环节,旨在构建一个高效、可落地的医疗AI数据标注解决方案,助力模型落地。

nft7creator的博客 297

双目视觉入门实战:用Matlab标定相机,再到Python OpenCV完成测距的完整链路

本文详细介绍了双目视觉技术的完整实现流程,从Matlab相机标定到Python OpenCV测距的全链路实践。重点解析了Matlab与OpenCV的参数转换技巧,以及立体校正、视差计算等关键步骤的代码实现,帮助开发者快速掌握双目测距系统的搭建方法。

weixin_29166013的博客 436

基于STM32F4XX 、HAL库的SHT40-CD1B-R3温湿度传感器驱动应用C语言程序设计

define SHT40_ADDR_READ 0x8B // CD1B 读地址 ((0x45 << 1) + 1)#define SHT40_ADDR_WRITE 0x8A // CD1B 写地址 (0x45 << 1)// 初始化 I2C1 (根据 CubeMX 生成的函数)// 湿度: -6%RH + 125%RH * (raw / 2^16)// 温度: -45°C + 175°C * (raw / 2^16)// 返回值: 0=成功, 1=失败(CRC错误或I2C通信错误)

PP_Cottage的博客 231

TC3XX - MCAL知识点(三十五):Tasking编译器下,Tc3xx的MCAL代码如何使用多核,多核中断、多核任务、多核外设之间的MCAL配置与代码例程

文章用于记录在裸机情况下使用多核Tc387芯片,如何高效运行以及正确的代码、工程属性、链接文件配置等问题,相互结合、相互影响的地方,以示后续使用记录。

梦想技术家 947

ANSYS——模态分析的理论基础

ANSYS模态分析理论基础

python_AI_fans的博客 8993

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: 进阶数据结构——双向循环链表
下一篇: 进阶数据结构——单调栈
yang Charles
博客等级 码龄3年 1507粉丝 95原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值