图的存储--邻接矩阵/边集数组/邻接表/链式邻接表/链式前向星

这篇具有很好参考价值的文章主要介绍了图的存储--邻接矩阵/边集数组/邻接表/链式邻接表/链式前向星。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

邻接矩阵

使用二维数组w[u][v]存储点u到点v的边的权值。一般应用在点数不多的稠密图
时间复杂度:O(n2)
空间复杂度:O(n2)
图的存储--邻接矩阵/边集数组/邻接表/链式邻接表/链式前向星

int w[N][N];		// edge
int vis[N];			// visited

void dfs(int u){
	vis[u] = true;
	for(int v = 1; v <= n; ++ v)
		if(w[u][v]){
			printf(%d, %d, %d\n", u,v,w[u][v]);
			if(vis[v]) continue;		// 防止重复访问
			dfs(v);
		}
}

int main(){
	cin >> n >> m;
	for(int i = 1; i <= m; ++ i){
		cin >> a >> b >> c;
		w[a][b] = c;
		w[b][a] = c;			// 无向图
	}
	dfs(1);
	return 0;
}

边集数组

边集数组e[i]存储第i条边的「起点、终点、边权」。在kruskal算法中,将边按边权排序,直接存边。
时间复杂度:O(nm)
空间复杂度:O(m)
图的存储--邻接矩阵/边集数组/邻接表/链式邻接表/链式前向星

struct edge{
	int u, v, w;
}e[M];
int vis[N];

void dfs(int u){
	vis[u] = true;
	for(int i = 1; i <= m; ++ i){		// 不知道节点后边有多少边。暴力枚举m次。
		if(e[i].u == u){				// 枚举以u做起点的边
			int v = e[i].v, w = e[i].w;
			printf(%d, %d, %d\n", u,v,w[u][v]);
			if(vis[v]) continue;
			dfs(e[i].v);
		}
}

int main(){
	cin >> n >> m;
	for(int i = 1; i <= m; ++ i){
		cin >> a >> b >> c;
		e[i] = {a, b, c};
		// e[i] = {b, a, c};	// 无向图
	}
	dfs(1);
	return 0;
}

邻接表

出边数组e[u][i]存储u的所有出边「终点v,边权w」。可以处理各种图,不能处理反向边。效率最高。
时间复杂度:O(n+m)
空间复杂度:O(n+m)
图的存储--邻接矩阵/边集数组/邻接表/链式邻接表/链式前向星

struct edge{int v, w};
vector<edge> e[N];		// 

void dfs(int u, int fa){
	for(auto ed : e[u]){
		int v = ed.v, w = ed.w;
		if(v == fa) continue;			// 终点等于父节点,防止循环访问
		printf(%d, %d, %d\n", u,v,w);
		dfs(v, u);
	}
}

int main(){
	cin >> n >> m;
	for(int i = 1; i <= m; ++ i){
		cin >> a >> b >> c;
		e[a].push_back({b, c});
		e[b].push_back({a, c});
	}
	dfs(1, 0);			// 假设1号节点的父节点是0
	return 0;
}

链式邻接表

边集数组e[j]存储第j条边的「起点u、终点v、边权w」。能处理反向边
表头数组h[u][i]存储u点的所有出边的编号
时间复杂度:O(n+m)
空间复杂度:O(n+m)
图的存储--邻接矩阵/边集数组/邻接表/链式邻接表/链式前向星

struct edge{int u, v, w};
vector<edge> e;			// 
vector<int> h[N];		// 点的所有出边

void add(int a, int b, int c){
	e.push_back({a, b, c});
	h[a].push_back(e.size() - 1);		// h记录该编号节点的所有出边的编号
}

void dfs(int u, int fa){
	for(int i = 0; i < h[u].size(); ++ i){ // u为起点的编号
		int j = h[u][i];				// j为终点的编号
		int v = e[j].v, w = e[j].w;
		if(v == fa) continue;			// 终点等于父节点
		printf(%d, %d, %d\n", u,v,w);
		dfs(v, u);
	}
}

int main(){
	cin >> n >> m;
	for(int i = 1; i <= m; ++ i){
		cin >> a >> b >> c;
		add(b, c);
		add(a, c);
	}
	dfs(1, 0);			// 假设1号节点的父节点是0
	return 0;
}

链式前向星

一个表头数组悬挂多个链表
边集数组e[i]存储第i条出边的「终点v、边权w、下一条边ne
表头数组h[u]存储u点的第一条出边的编号
边的编号idx可取0,1,2,3

时间复杂度:O(n+m)
空间复杂度:O(n+m)
图的存储--邻接矩阵/边集数组/邻接表/链式邻接表/链式前向星文章来源地址https://www.toymoban.com/news/detail-431872.html

struct edge{int v, w, ne};	// 终点、边权、下一条边编号
edge e[M];				// 边集
int idx, h[N];			// 第一条出边

void add(int a, int b, int c){
	e[idx] = {b, c, h[a]};	// 每个点后加的第一条边的h值一定是-1
	h[a] = idx++;		// idx记录边的编号,没加一条边就增加1。头插法,先插后访问。
}

void dfs(int u, int fa){
	// -1取反为0
	for(int i = h[u]; ~ i; i = e[i].ne){ // u为起点的编号,h[u]就是u节点第一条出边编号
		int v = e[i].v, w = e[i].w;
		if(v == fa) continue;			// 终点等于父节点
		printf(%d, %d, %d\n", u,v,w);
		dfs(v, u);
	}
}

int main(){
	cin >> n >> m;
	memset(h, -1, sizeof h);		// 表头初始化为-1,遍历到-1说明结束
	for(int i = 1; i <= m; ++ i){
		cin >> a >> b >> c;
		add(a, b, c);
		add(b, a, c);
	}
	dfs(1, 0);			// 假设1号节点的父节点是0
	return 0;
}

到了这里,关于图的存储--邻接矩阵/边集数组/邻接表/链式邻接表/链式前向星的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 蓝桥集训之BFS、DFS和链式前向星

    https://www.bilibili.com/video/BV1RD4y1F7Fq 图一般定义为 二元集 ; 由 顶点集 与 边集 构成。 或者更抽象的说,由一个集合(顶点),和集合上的关系(边)构成 邻接矩阵 邻接表 度,出度,入度 在有向图中,箭头是具有方向的,从一个顶点指向另一个顶点,这样一来,每个顶点 被指

    2023年04月09日
    浏览(39)
  • SPFA + 链式前向星建图【附Java模板】

                                                                                 SPFA算法是什么?它能解决什么样的问题?           🌷 仰望天空,妳我亦是行人.✨ 🦄 个人主页——微风撞见云的博客🎐 🐳 数据结构与算法专栏的文章

    2024年02月06日
    浏览(38)
  • 算法复习6.1链式前向星(代码块式理解)

    一号初始节点head[1]=3(cnt=3)指向四号节点 edge[3(cnt=3)],其中edge[3].to=4 即四号节点 ,同时令edge[3].next=(new)cnt 指向下一个 ... (循环) 有点像指针,如果功能不复杂的话,可以直接简写为vector快捷操作  

    2024年02月21日
    浏览(63)
  • 【图论C++】树的重心——教父POJ 3107(链式前向星的使用)

    UpData Log👆 2023.9.26 更新进行中 Statement0🥇 一起进步 Statement1💯 有些描述是个人理解,可能不够标准,但能达其意 树 是 图 的一种 特例 , 树 就是 “没有环” 的 连通图 判断一个 图 是否是一个 树 ,需要满足的条件: 1)树根 :一棵树可以基于 无向图 与 有向图 ,区别在

    2024年02月07日
    浏览(43)
  • 图的存储 —— 邻接矩阵

    图的结构比较复杂,任何两个节点之间都可能有关系。 图的存储分为顺序存储和链式存储。 顺序存储包括邻接矩阵和边集数组, 链式存储包括邻接表、链式前向星、十字链表和邻接多重表。 图的存储 —— 邻接矩阵 邻接矩阵通常采用一个一维数组存储图中节点的信息,采用

    2024年02月06日
    浏览(42)
  • 数据结构——图的基本定义以及图的存储结构,邻接矩阵,邻接表

    目录 图的定义和术语 图的存储结构 顺序存储结构—邻接矩阵 链式存储结构 邻接表 邻接多重表 十字链表 图的遍历 图的连通性问题 有向无环图及其应用 最短路径 图的定义:图是一种非线性的复杂的数据结构,图中的数据元素的关系是多对多的关系 ,在图中我们常常把数

    2024年02月04日
    浏览(58)
  • 图的邻接矩阵存储及遍历操作

    任务描述 本关任务:要求从文件输入顶点和边数据,包括顶点信息、边、权值等,编写程序实现以下功能。 1)构造无向网G的邻接矩阵和顶点集,即图的存储结构为邻接矩阵。 2)输出无向网G的各顶点和邻接矩阵。 3)输出无向网G中顶点H的所有邻接顶点。 测试说明 平台会对

    2024年02月06日
    浏览(40)
  • 24考研数据结构-图的存储结构邻接矩阵

    【1】顶点的结点结构 ——————— | data | firstarc | ——————— data数据域:储存顶点vi firstarc链域:指向链表中第一个结点 【2】弧的结点结构 —————————— | adjvex | info | nextarc | —————————— adjvex邻接点域:与顶点vi邻接的点在图中的位置 info数据域

    2024年02月14日
    浏览(57)
  • 6-1 邻接矩阵存储图的深度优先遍历

    分数 20 作者 DS课程组 单位 浙江大学 试实现邻接矩阵存储图的深度优先遍历。 其中MGraph是邻接矩阵存储的图,定义如下: 函数DFS应从第V个顶点出发递归地深度优先遍历图Graph,遍历时用裁判定义的函数Visit访问每个顶点。当访问邻接点时,要求按序号递增的顺序。题目保证

    2024年02月05日
    浏览(41)
  • 图详解第一篇:图的基本概念及其存储结构(邻接矩阵和邻接表)

    这篇文章开始,我们来学习一种高阶数据结构——图 图是由顶点集合及顶点间的关系(边)组成的一种数据结构:G = (V, E)。 其中: 顶点集合V = {x|x属于某个数据对象集}是有穷非空集合; E = {(x,y)|x,y属于V}或者E = {x, y|x,y属于V Path(x, y)}是顶点间关系的有穷集合,也叫做边的集

    2024年02月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包