呀,图真是一个令人头疼而又很重要的东西。在现实生活中,我们有很多的问题都不能用树来实现,所以烦人啊不伟大的图就出现了——

图的存储

没有存储哪来的操作,所以存储是最基础的呢。

邻接矩阵

我们对于图的存储需要存储顶点和边的信息,最简单的就是邻接矩阵的方法了。

如果我们想要存储这样的一张图

就可以使用到我们的好伙伴二维数组来帮忙了,具体点来说,如果有一张有 个点的图,那么我们就可以使用 N×N 的二维数组来存储。数组的每个元素的值代表了对应的边的数量。就像这个样子——

这样可以很方便快捷地存储一些很稠密的图,而且可以很快速地定位到某条边。

代码长这样——

 scanf("%d",&n);
for(int i = ; i <= n; i++){
scanf("%d%d",&x,&y);
a[x][y] = a[y][x] = ;//无向图,x->y和y->x都要存
}

*敲代码的时候注意有向图和无向图^=^

权矩阵

若边有权,就用A[i,j]存储边<i,j>的权。若没有边则默认无穷大。

代码长这样——

 scanf("%d",&n);
memset(a,0x3f,sizeof(a));
for(int i = ; i <= n; i++){
scanf("%d%d%d",&x,&y,&w);
a[x][y] = a[y][x] = w;
}

我们用邻接矩阵存图的时候需要开一个二维数组来存边,空间会很大,更适合一些稠密图。对于一些点多边少的图,空间和时间的代价也会随之增加,所以我们需要设计一个数据结构用来记录与其相连的边之间的联系。

So,我们优秀的代表邻接表就出现了——

邻接表

(小声BB:虽然我们老师一直叫它链式前向星,但我一直没明白前向星是什么东东)

邻接表把与顶点相连的所有边依次来拿成一条链,并新建一个元素在定点与这条链的开端建立一个联系,这样我们可以通过顶点的初始链接访问到与这个顶点相连的第一条边,再沿着这条链依次往后访问下一条边。(此文出自CCF中学生计算机程序设计提高篇P77)

当然它也可以用来存树。

代码长这样——

 struct edge{
int to,nxt,w;
}e[]; void addedge(int u,int v){
e[++tot].to=v;
e[tot].nxt=head[u];
e[tot].w = w;//存权~
head[u]=tot;
}

看着有点神奇,其实也没有那么复杂,手动模拟一下就能明白了。

首先我们假设我们有这样的一张图——

一共7条边(u,v):

① 1 --> 2       ⑤ 2 --> 4

② 1 --> 5       ⑥ 2 --> 3

③ 2 --> 5       ⑦ 3 --> 4

④ 4 --> 5

我们需要几个东西:

tot 用来记录有几条边

e[] 用来记录边与点与边之间的关系

head[] 用来记录点最后一条存储的边的序号

首先我们先把所有的数组值初始化为-1

存第一条边 ① 1 --> 2时,tot = 1

就会变成这样——

存第二条边 ② 2 --> 4,tot  = 2

就会变成这样——

将它们全部模拟一遍就会变成这个样子——

(应该没错吧)

然后我们就巧妙地获得了点与边之间的关系,那应该怎么运用呢?那就是图的遍历啦~

图的遍历

邻接矩阵没什么好讲的啦,循环一遍就OK。我们重点来talk about邻接表

我们刚刚经过一系列的折腾操作得到了点与边之间的联系,当然得好好地利用啊。

当我们想从 u 点遍历整张图or树时,让 指向 head[u],如果 i != -1,i 就可以指向 e[i].nxt 去寻找下一条边。

代码长这样——

 void dfs(int u){
vis[u] = ;//搜过了标记一下,无向图以防重复搜,树以防搜到它爸爸
for(int i = head[u]; i; i = e[i].nxt){
int v = e[i].to;
if(vis[v]) continue;
dfs(v);
}
}

这样子我们就可以顺着一个个点一条条边有序地遍历一整张图,如果还不清晰的话就自己手动模拟一遍吧。

这种做法我第一次知道的时候感觉它特别神奇,几个看不出什么关系的数(也可能是我太菜了)竟然可以让我们遍历整张图。

事实证明它确实很好用(多半是学校老师逼得),但这并不影响我对它初见面时惊讶的看法。

相信你们肯定也能体会到它的好处的~

总结一下

图是个挺重要的东西,把一张图用几个数字所记录,对于我来说是把具体变成抽象,是个不小的挑战。

写这篇东西主要是想多巩固巩固基础,也希望大家看了之后能有收获。

拜拜~

(如果文章有不对的地方,请指出,谢谢啦^=^)

【lhyaaa】图的存储&遍历的更多相关文章

  1. 图的存储及遍历 深度遍历和广度遍历 C++代码实现

    /*图的存储及遍历*/ #include<iostream> using namespace std; //----------------------------------- //邻接 ...

  2. 图的存储,搜索,遍历,广度优先算法和深度优先算法,最小生成树-Java实现

    1)用邻接矩阵方式进行图的存储.如果一个图有n个节点,则可以用n*n的二维数组来存储图中的各个节点关系. 对上面图中各个节点分别编号,ABCDEF分别设置为012345.那么AB AC AD 关系可以 ...

  3. C++编程练习(9)----“图的存储结构以及图的遍历“(邻接矩阵、深度优先遍历、广度优先遍历)

    图的存储结构 1)邻接矩阵 用两个数组来表示图,一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中边或弧的信息. 2)邻接表 3)十字链表 4)邻接多重表 5)边集数组 本文只用代码实现用 ...

  4. PTA 邻接矩阵存储图的深度优先遍历

    6-1 邻接矩阵存储图的深度优先遍历(20 分) 试实现邻接矩阵存储图的深度优先遍历. 函数接口定义: void DFS( MGraph Graph, Vertex V, void (*Visit)( ...

  5. PTA 邻接表存储图的广度优先遍历(20 分)

    6-2 邻接表存储图的广度优先遍历(20 分) 试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(V ...

  6. 邻接矩阵实现图的存储,DFS,BFS遍历

    图的遍历一般由两者方式:深度优先搜索(DFS),广度优先搜索(BFS),深度优先就是先访问完最深层次的数据元素,而BFS其实就是层次遍历,每一层每一层的遍历. 1.深度优先搜索(DFS) 我一贯习惯有 ...

  7. 【algo&ds】6.图及其存储结构、遍历

    1.什么是图 图表示"多对多"的关系 包含 一组顶点:通常用 V(Vertex)表示顶点集合 一组边:通常用 E(Edge)表示边的集合 边是顶点对:(v,w)∈ E,其中 v,w ...

  8. PTA 邻接表存储图的广度优先遍历

    试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ) 其中LGraph是邻接表存储的 ...

  9. 图的存储与遍历C++实现

    1.图的存储 设点数为n,边数为m 1.1.二维数组 方法:使用一个二维数组 adj 来存边,其中 adj[u][v] 为 1 表示存在 u到 v的边,为 0 表示不存在.如果是带边权的图,可以在 a ...

随机推荐

  1. 对掌机游戏Pokemon的一部分系统的拆解流程图

    整体系统拆解 POKEMON系统拆解 属性.技能.进化形态 属性提升系统 种族值说明: 所有Pokemon都拥有自己的种族的种族值,且固定(例如:小火龙:309, 皮卡丘: 320) 种族值是各项属性 ...

  2. commons-fileload图片文件上传工具 , servlet文件图片上传案列

    本案列是java  maven工程小项目,提供个大家学习! 1.在pom.xml文件中导入依赖: <!--文件上传依赖--><dependency> <groupId&g ...

  3. Python Ethical Hacking - Bypass HTTPS(1)

    HTTPS: Problem: Data in HTTP is sent as plain text. A MITM can read and edit requests and responses. ...

  4. 集训作业 洛谷P1032 字串变换

    集训的题目有点多,先写困难的绿题吧(简单的应该想想就会了) 嗯,这个题看起来像个搜索呢(就是个搜索) 我们仔细想想就知道这个题肯定不能用深搜,可以优化的地方太少了,TLE是必然的. 那我们该怎么办呢? ...

  5. Angular 的前世今生

    目录 序言 AngularJS 简介 Angular 2.0 的动机 现如今的 Angular Angular 的核心概念 参考 序言 Angular 一般意义上是指 Angular v2 及以上版本 ...

  6. 一起学Blazor WebAssembly 开发(1)

    最近blazor的WebAssembly 正式版出来了,正好手头有一个项目采用的前后端分离模式做的,后端用的abp vnext(.net core 的一个很著名的框架)框架开发的,其实前端之前考虑的使 ...

  7. centos7+jexus5.8.3部署ASP.NET的MVC项目

    1.在centos7终端以root权限安装jexus5.8.3的独立版 命令:curl https://jexus.org/release/x64/install.sh|sh 2.跳转到目录/usr/ ...

  8. 任务调度中心xxl-job对外接口使用

    xxl-job主要分为调度中心和执行器提供了图像化界面,操作简单上手快,基本实现定时任务自动执行,同时可以针对任务日志进行查看.具体xxl-job可以再github上下载:https://github ...

  9. 为什么Python适合初学者,一般要学习多久

    为什么Python适合初学者?一般Python要学习多久?很多人都觉得,Python是一门很好学的语言,非常适合入门.但更多人都是不清楚具体原因的.那么,我们不如一起来看看Python为何更适合初学者 ...

  10. MySQL组复制MGR(二)-- 组复制搭建

    (一)主机操作 (1)路由信息vmnet5 192.168.10.0 (2)主机信息 主机名称 IP地址 操作系统版本 数据库版本 mgr-node1 192.168.10.11 centos 7.4 ...