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

图的存储

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

邻接矩阵

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

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

就可以使用到我们的好伙伴二维数组来帮忙了,具体点来说,如果有一张有 N 个点的图,那么我们就可以使用 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树时,让 i 指向 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. linux专题(六):Vim编辑器

    http://dwz.date/UDf 什么是Vim编辑器 Vim是从 vi 发展出来的一个文本编辑器.代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用. 简单的来说, vi 是 ...

  2. Python Ethical Hacking - BACKDOORS(2)

    Refactoring - Creating a Listener Class #!/usr/bin/env python import socket class Listener: def __in ...

  3. View Animation 运行原理解析

    Android 平台目前提供了两大类动画,在 Android 3.0 之前,一大类是 View Animation,包括 Tween animation(补间动画),Frame animation(帧 ...

  4. 写给程序员的机器学习入门 (八) - 卷积神经网络 (CNN) - 图片分类和验证码识别

    这一篇将会介绍卷积神经网络 (CNN),CNN 模型非常适合用来进行图片相关的学习,例如图片分类和验证码识别,也可以配合其他模型实现 OCR. 使用 Python 处理图片 在具体介绍 CNN 之前, ...

  5. DJANGO-天天生鲜项目从0到1-001-环境框架搭建

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  6. 面试题二十二:链表中倒数第k个节点

    方法一:双指针法定义两个指针A.B,A先走k-1步后再一起走,直到A.next==null注意: 1.链表为空 2.链表长度小于k 3.k<=0 当题目是求链表的中间节点时,可以两个指针从开头开 ...

  7. 网页批量打印成PDF,并按条件合并成大PDF、生成页码

    题记:因为老板要求将过去一年内系统中的订单合同内容进行打印,并按月进行整理成纸质文件.合同在系统(web系统)中以html形式显示,打印单份都是在网页中右键打印,订单量上千份,每笔订单有两份合同,如果 ...

  8. 人工智能?.netcore一样胜任!

    提起AI,大家都会先想到Python,确实Python作为一门好几十年的老语言,上一波的AI大流行使它焕发了青春.大家用Phtyon来做AI,最主要的原因无非就是编码量更少,很多数学和AI相关的Api ...

  9. Linux系统的基本操作

    20200727 Linux目录结构 基本介绍 Linux的文件系统是采用层级式的树状结构,在此结构中的最上层是/根目录 tip1:在Linux世界里,一切皆是文件 示例 /bin: bin是Bina ...

  10. 使用 MySQLi 和 PDO 向 MySQL 插入多条数据

    PHP MySQL 插入多条数据 使用 MySQLi 和 PDO 向 MySQL 插入多条数据 mysqli_multi_query() 函数可用来执行多条SQL语句. 以下实例向 "MyG ...