【邻接表存图模板】vector邻接表、数组邻接表、链式前向星

一、目录

一、目录

二、前言

三、邻接表“详解”

(一)边的信息

(二)几种邻接表的实现方法“详解”

1.数组邻接表

代码

2.vector邻接表

代码

vector邻接表还有一种魔性写法:

3.链式前向星

代码

四、总结


二、前言

本来之前自己太弱了,一直只会用邻接矩阵,后来发现邻接表才是主流...

参考&特别鸣谢:

https://www.cnblogs.com/dilthey/p/9016321.html

https://www.cnblogs.com/ECJTUACM-873284962/p/6905416.html

三、邻接表“详解”

专业邻接表知识许多博客和书上都阐述得很详尽了,

自己这里只是简单地解析,可能用语不太准确,主要目的是用自己懂的方式解释一下

(一)边的信息

1.对于每条边而言:

一般做题时题目会提供很多关于每条边的信息,如边权、点权,这时我们要把需要的信息存下来

一般有三个:u—边的起始端点、v—边的终止端点、w—边权or长度,

常规用结构体储存:

struct edge
{
    int u,v,w;
    edge(int _u=0,int _v=0,int _w=0){u=_u,v=_v,w=_w;}
    //edge(edge &e){u=e.u,v=e.v,w=e.w;}
};

2.对于整个图而言:

知道了每条边的信息,还要把它们按照题目所给的关系连起来,组成一个完整的图

对于每条边,想要让它和其他边连起来,肯定会想到一个关键信息:

next / to——该边与之相连的边的编号

这部分就会涉及到不同的实现方法了,方法不同,关键信息也不同


(二)几种邻接表的实现方法“详解”

1.数组邻接表

第一行两个整数n m。n表示顶点个数(顶点编号为1~n),m表示边的条数。接下来m行表示,每行有3个数x y z,表示顶点x到顶点y的边的权值为z。下图就是一种使用链表来实现邻接表的方法。

上面这种实现方法为图中的每一个顶点(左边部分)都建立了一个单链表(右边部分)。这样我们就可以通过遍历每个顶点的链表,从而得到该顶点所有的边了。使用链表来实现邻接表对于痛恨指针的的朋友来说&#

### 关于邻接表链式前向星的数据结构例题实现 #### 使用邻接表表示并解决最短路径问题 对于给定的一个无权有向,使用邻接表来表示该,并求解从源点到其他各顶点的最短距离。 ```cpp #include <iostream> #include <vector> #include <queue> using namespace std; const int MAXN = 1e5 + 7; int dist[MAXN]; bool vis[MAXN]; // 定义边结构体 struct Edge { int to, next; } edge[MAXN * 2]; // 假设最多有MAXN*2条边 int head[MAXN], cnt; // head数组记录每个节点的第一条出边编号;cnt用于计数当前已有的边数量 void addEdge(int from, int to) { // 添加一条from->to方向上的边 edge[++cnt].to = to; edge[cnt].next = head[from]; head[from] = cnt; } void bfs(int startNode) { queue<int> q; memset(dist, -1, sizeof(dist)); dist[startNode] = 0; q.push(startNode); while (!q.empty()) { int cur = q.front(); q.pop(); for (int i = head[cur]; ~i; i = edge[i].next) { int v = edge[i].to; if (dist[v] == -1) { dist[v] = dist[cur] + 1; q.push(v); } } } } ``` 这段代码展示了如何利用邻接表构建一张简单的无权有向以及通过广度优先搜索算法计算起始节点到达其余各个节点之间的最小步数[^1]。 #### 利用链式前向星处理加权中的最短路问题 下面的例子说明了怎样运用链式前向星存储带权重的边信息,并借助Dijkstra算法找出单源最短路径: ```cpp #include <cstring> #include <algorithm> #define INF 0x3f3f3f3f using namespace std; typedef pair<int,int> PII; const int N=1e5+10,M=N<<1; int n,m,S,T,d[N]; PII e[M]; int h[N],ne[M],w[M],idx; bool st[N]; inline void add(int a,int b,int c){ e[idx]=make_pair(b,c),ne[idx]=h[a],h[a]=idx++; } void dijkstra(){ memset(d,INF,sizeof d); priority_queue<PII,vector<PII>,greater<>> heap; d[S]=0; heap.push({d[S],S}); while(heap.size()){ auto t=heap.top(); heap.pop(); int ver=t.second,dis=t.first; if(st[ver]) continue; st[ver]=true; for(int i=h[ver];~i;i=ne[i]){ int j=e[i].first; if(d[j]>dis+w[i]){ d[j]=dis+w[i]; heap.push({d[j],j}); } } } } ``` 此部分实现了基于链式前向星的方式保每条边上附带的成本值,并且采用了堆优化版迪杰斯特拉(Dijkstra)算法去查找由指定起点出发至其它任意终点间的最优路线长度[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值