链式前向星存图 详细解析

article/2025/10/16 9:12:30

文章目录

  • 链式前向星
    • 完整代码

链式前向星

链式前向星是一种图的存储方式,相比于 邻接矩阵和邻接表 ,链式前向星是一种静态链表存储,用边集数组和邻接表相结合,可以快速访问一个顶点的所有邻接点。

在某些算法题中使用还很频繁,我就是因为看不懂别人发的题解,所以就学习了这种存储图的方式。


不多啰嗦,也许你看别人发的题解中都有这样一段代码:

void add_edge(int u, int v, int w)
{edge[cnt].to = v;edge[cnt].w = w;edge[cnt].next = head[u];head[u] = cnt++;
}

你是否在一开始有和我一样的疑惑,这是个什么东西???

这就是链式前向星的加边操作(add_edge),和邻接表,邻接矩阵一样,这就是增加一条由 u 指向 v 的边的操作,如果是带权边,则边权就是w


链式前向星的数据结构:

const int N=10005;
struct Edge
{int to,w,next;
}edge[N];
int head[N],cnt;

如上,我们使用一个结构体和两个变量便可以描绘出链式前向星

结构体:

  • to 代表这条边的终点
  • w 代表这个边的权值(如果是带权边)
  • next 代表与这条边起点相同的上一条边的编号
  • head 代表head[i],以i为起点的最后一条边的编号
  • cnt 代表边的数量

这个next到底是什么意思???

看这个图:3的next 就表示与3的起点1为起点,的上一条边的编号是 2

如果这是一个树结构,则就表示的是当前节点的兄弟节点,不过是最近的,所以是以这条边的起点相同的上一条边的编号
在这里插入图片描述


head的含义:
head数组始终记录以 1 为起点的最后一条边的编号,图中操作完成后 head[1]=3
在这里插入图片描述

表示 以 1 作为起点的最后一条边的编号,

  • 2号节点连接时,head[1] 表示 2号节点;
  • 3节点进入后,head[1]表示3号节点。

接下来我们就来解析 上面那段函数代码

void add_edge(int u, int v, int w)
{edge[cnt].to = v;	//终点为vedge[cnt].w = w;	//边权edge[cnt].next = head[u];	//以u为起点的上一条边的编号为head[u]head[u] = cnt++;	//更新以u为起点的最后一条边的编号为cnt
}
  • edge[cnt].to = v :添加一条从 u -> v的边
  • edge[cnt].w = w:u->v这条边的边权是w
  • edge[cnt].next = head[u]:
    • edge[cnt].next:表示以 u 为起点的上一条边的编号
    • head[u]:以u为起点的最后一条边的编号。
    • 连起来就表示:以u为起点的上一条边的编号为 head[u]
  • head[u] = cnt++:更新以u为起点的最后一条边的编号

下面我借助例子来说明一下:

5 7
1 2 1
2 3 2
3 4 3
1 3 4
4 1 5
1 5 6
4 5 7

对于1 2 1这条边:edge[0].to = 2; edge[0].next = -1; head[1] = 0;

对于2 3 2这条边:edge[1].to = 3; edge[1].next = -1; head[2] = 1;

对于3 4 3这条边:edge[2].to = 4; edge[2],next = -1; head[3] = 2;

对于1 3 4这条边:edge[3].to = 3; edge[3].next = 0; head[1] = 3;

对于4 1 5这条边:edge[4].to = 1; edge[4].next = -1; head[4] = 4;

对于1 5 6这条边:edge[5].to = 5; edge[5].next = 3; head[1] = 5;

对于4 5 7这条边:edge[6].to = 5; edge[6].next = 4; head[4] = 6


那么经过我们的努力理解,我们终于明白了这个函数的作用,其实还有另外一种写法

void add_edge(int u, int v, int w)
{edge[++cnt].to = v;	//终点为vedge[cnt].w = w;	//边权edge[cnt].next = head[u];	//以u为起点的上一条边的编号为head[u]head[u] = cnt;	//更新以u为起点的最后一条边的编号为cnt
}

看出区别了吗,其实就是 第一行的edge的 cnt提前++,其实和上面是一致的,前一个从0开始,这个的话就是从1 开始。


对于初始化,我们直接把head memset 为 -1即可,这样就表示所有起点的最后一条边的编号为 -1,即表示没有边


对于遍历函数:

void show()
{for (int i = 1; i <= n; i++){for (int j = head[i]; j != -1; j = edge[j].next){//1: 6 4 2 cout << i << " -> " << edge[j].to << ": " << edge[j].w << endl;}cout << endl;}
}

由于head[i] 存储了 以i为起点的最后一条边的编号,则我们目前对于 i 所在的边集合进行操作,则 j 表示的就是与 i 相连的边的编号,便可以通过 edge来获得 j 的终点权值;进而往前寻找以i为起点的上一条边的编号,进而往前遍历到所有连接的边。


main函数怎么写???

init();
scanf("%d%d", &n, &m);
for (int i = 1; i <= n - 1; i++)
{int ui, vi, wi;scanf("%d%d%d", &ui, &vi, &wi);add_edge(ui, vi, wi);add_edge(vi, ui, wi);//建双向无向边 
}

注意我们这是 建双向无向边,我们可以只使用一个add_edge来建单向边

完整代码

#include <bits/stdc++.h>
using namespace std;const int N = 10005;
struct Edge
{int to, w, next;//起点,边权,以这条边为起点的上一条边的编号
}edge[N];//边集int n, m;//n个点,m条边
int head[N], cnt;//head[i]表示以i为起点的最后一条边的编号
void init()
{for (int i = 1; i <= N; i++){head[i] = -1;//以i为起点的最后上一条边的编号默认为-1}cnt = 0;
}
void add_edge(int u, int v, int w)
{edge[cnt].to = v;	//终点为vedge[cnt].w = w;	//边权edge[cnt].next = head[u];	//以u为起点的上一条边的编号为head[u]head[u] = cnt++;	//更新以u为起点的最后一条边的编号为cnt
}
void show()
{for (int i = 1; i <= n; i++){for (int j = head[i]; j != -1; j = edge[j].next){//1: 6 4 2 cout << i << " -> " << edge[j].to << ": " << edge[j].w << endl;}cout << endl;}
}void test1()
{cin >> n >> m;init();for (int i = 1; i <= n-1; i++){int u, v, w;cin >> u >> v >> w;add_edge(u, v, w);	//}show();
}int nxt[N], to[N], val[N];//这是一堆建边要用的东西qaq 
void add_edge2(int u, int v, int w)//邻接链表建边..貌似没什么好说的 
{nxt[++cnt] = head[u];head[u] = cnt;to[cnt] = v;val[cnt] = w;
}
void test2()
{init();scanf("%d%d", &n, &m);for (int i = 1; i <= n - 1; i++){int ui, vi, wi;scanf("%d%d%d", &ui, &vi, &wi);add_edge2(ui, vi, wi);add_edge2(vi, ui, wi);//建无向边 }
}
int main()
{/*5 21 3 11 4 102 3 203 5 20*/test2();return 0;
}................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

http://chatgpt.dhexx.cn/article/ZlZjpfvp.shtml

相关文章

C++之链式前向星

链式前向星 基本定义以及实现链式前向星实现DFSBFS 基本定义以及实现 (若果有一定了解&#xff0c;可以跳过第一部分&#xff0c;直接看第二部分) 我们首先来看一下什么是前向星. 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按…

图的存储 —— 链式前向星

图的存储 —— 链式前向星 链式前向星采用了一种静态链表存储方式&#xff0c;将边集数组和邻接表相结合&#xff0c;可以快速访问一个节点的所有邻接点&#xff0c;在算法竞赛中被广泛应用。 链式前向星有如下两种存储结构。 边集数组&#xff1a;edge[]&#xff0c;edge[i…

简述链式前向星

一、前言 我们常见的存图数据结构有两种&#xff0c;一种是邻接矩阵&#xff0c;另一种是邻接表。而在邻接矩阵中&#xff0c;空间复杂度为 O ( n 2 ) O(n^2) O(n2)&#xff0c;在稀疏图的情况下&#xff0c;相较于邻接表浪费了许多空间。而常规的邻接表是用链表进行操作&…

链式前向星 详解

链式前向星 链式前向星是一种类似于邻接表的存图方式&#xff0c;同样适用于有向 图和无向图。 他建立的是边与边之间的联系 它将边里的所有边都进行编号 int cnt; //边的编号 struct edge{ //边的结构体int from,to,w,next; //from是边的起点&#xff08;这个可有可无&a…

用链式前向星存储图

图最常用的存储结构主要是邻接矩阵和邻接表。当顶点数太大时&#xff0c;用二维数组表示的邻接矩阵可能超内存&#xff08;MLE&#xff09;&#xff0c;而用邻接表的编码工作量较大&#xff0c;此时&#xff0c;使用vector数组或链式前向星模拟邻接表是不错的选择。因vector数组…

链表、链式前向星

讲链表的时候就卡在这里了&#xff0c;最短路又卡在链式前向星上了&#xff0c;毕竟是图论基础&#xff0c;觉得还是有必要写一写防止下次再懵。 链表都是头插法&#xff01;&#xff01;即每次我们给他插一个头。 普通链表 先初始化令head-1,idx-1. void add_tohead(int x…

链式前向星(详细讲述)

在dalao的压迫下本蒟蒻发个博客&#xff0c;给大家讲一下链式前向星&#xff08;新手&#xff0c;写错了轻喷&#xff09; 首先说明一点链式前向星适合于稀疏图&#xff0c;而邻接矩阵则更适合稠密图&#xff0c;所以最好看好数据范围再决策使用哪个方法&#xff0c;当然有些题…

链式前向星与邻接表对比

本文图片及数据 对于这样一张有向图&#xff1a; 输入边的顺序如下&#xff1a; 1 2 2 3 3 4 1 3 4 1 1 5 4 5 对于邻接表来说是这样的&#xff1a; 1 -> 2 -> 3 -> 5 2 -> 3 3 -> 4 4 -> 1 -> 5 5 ->^ 对于链式前向星来说是这样的&…

链式前向星存图(有图详解)

链式前向星:既然是链式那么肯定和链表相关,前向星是每次指向都向前 链式前向星存图是以边为中心,并不是以结点为中心,它记录的是边的一些属性,包括边边的id、头节点、尾结点、权值、边的指向! 边的指向是遍历图的时候需要按照一定顺序去遍历,而不能胡乱的去遍历,那么就需要这些…

链式前向星的详解

目录 1&#xff1a;链式前向星的概念解释 2&#xff1a;代码展现 链式前向星是一种非常好用的有向图存储方式&#xff0c;但是它的代码难度却有点大。作者在这上面花了很长的时间才弄懂。虽然有其他的博客大佬写的很好&#xff0c;但总感觉不太适合小白选手&#xff08;比如说…

链式前向星基本原理

一、概述 我们在学习图论的时候学习了一种图的存储结构--二维数组邻接矩阵储存&#xff0c;他虽然可以表达直观&#xff0c;快速访问连接两点的边&#xff0c;但是它占用空间大&#xff0c;只适用于点少的图&#xff0c;所以我们需要一种能够可以存储大型图的东西--链式前向星…

链式前向星的原理图解

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

【链式前向星+存图】讲解

大佬的链式前向星:https://blog.csdn.net/acdreamers/article/details/16902023 【前向星】&#xff1a; 解释一下&#xff1a; 【前向星和链式前向星的不同】&#xff1a; 【给出链式前向星的代码实现】&#xff1a; #include<bits/stdc.h> using namespace std; #def…

链式前向星——最完美图解

图的存储方法很多,最常见的除了邻接矩阵、邻接表和边集数组外,还有链式前向星。链式前向星是一种静态链表存储,用边集数组和邻接表相结合,可以快速访问一个顶点的所有邻接点,在算法竞赛中广泛应用。 链式前向星存储包括两种结构: 边集数组:edge[ ],edge[i]表示第i条边…

链式前向星(详解)

链式前向星&#xff08;详解&#xff09; 转自&#xff1a;传送门 我们首先来看一下什么是前向星. 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序, 并记录下以某个点为起点的所有边在数组中的起始位置和…

链式前向星

一 点睛 链式前向星采用了一种静态链表存储方式&#xff0c;将边集数组和邻接表相结合&#xff0c;可以快速访问一个节点的所有邻接点。 链式前向星有如下两种存储结构。 1 边集数组 edge[],edge[i] 表示第 i 条边。 2 头节点数组 head[],head[i] 存储以 i 为起点的第1条边…

深度理解链式前向星

我们首先来看一下什么是前向星. 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序, 并记录下以某个点为起点的所有边在数组中的起始位置和存储长度,那么前向星就构造好了. 用len[i]来记录所有以i为起点的边在数…

链式前向星(超详细)

前向星和链式前向星 链式前向星 添加边的操作 链式前向星&#xff0c;就是以链式结构来储存前向星&#xff0c;每条边就要用结构体&#xff0c;结构体中包含三个数据&#xff1a; Edge[i].to &#xff1a;第i条边的终点 Edge[i].next &#xff1a;与第i条边同一个起点的下…

stm32串口中断的接收

利用串口使得led点亮 利用之前的串口函数加上NVIC的中断函数结构体 定义结构体 定义 配置抢占优先级的组别 配置NVIC串口中断的结构体&#xff1a;中断的通道&#xff0c;配置抢占优先级和子优先级 使能CMD 结构体初始化 还有需要配置中断串口的配置&#xff1a; 串口 接…

STM32串口下载

使用FlyMCU下载程序 1.上电前&#xff0c;设置BOOT01&#xff0c;BOOT10。或者是在上电后&#xff0c;设置BOOT01&#xff0c;BOOT10之后&#xff0c;然后按一下复位按键&#xff0c;从而通过串口下载程序。 2.&#xff0c;在MDK编译加载生成的hex文件&#xff0c;并勾选右边的…