作者 | 小灰

责编 | 郭芮

图的概念

究竟什么是图呢?大家先来想一想咱们常用的互联网产品。

举个栗子,大家一定都用过微信,假设你的微信朋友圈中有若干好友:张三、李四、王五、赵六、七大姑、八大姨。

而你七大姑的微信号里,又有若干好友:你、八大姨、Jack、Rose。

微信中,许许多多的用户组成了一个多对多的朋友关系网,这个关系网就是数据结构当中的图(Graph)

再举一个栗子,咱们在用百度地图的时候,常常会使用导航功能。比如你在地铁站A附近,你想去的地点在地铁站F附近,那么导航会告诉你一个最佳的地铁线路换乘方案。

这许许多多地铁站所组成的交通网络,也可以认为是数据结构当中的图。

图,是一种比树更为复杂的数据结构。树的节点之间是一对多的关系,并且存在父与子的层级划分;而图的顶点(注意,这里不叫节点)之间是多对多的关系,并且所有顶点都是平等的,无所谓谁是父谁是子。

图的术语

下面我们来介绍一下图的基本术语:

在图中,最基本的单元是顶点(vertex),相当于树中的节点。顶点之间的关联关系,被称为边(edge)

在有些图中,每一条边并不是完全等同的。比如刚才地铁线路的例子,从A站到B站的距离是3公里,从B站到C站的距离是5公里......这样就引入一个新概念:边的权重(Weight)。涉及到权重的图,被称为带权图(Weighted Graph)

还有一种图,顶点之间的关联并不是完全对称的。还拿微信来举例,你的好友列表里有我,但我的好友列表里未必有你。

这样一来,顶点之间的边就有了方向的区分,这种带有方向的图被称为有向图

相应的,在QQ当中,只要我把你从好友里删除,你在自己的好友列表里也就看不到我了。(貌似是这样)

因此,QQ的好友关系可以认为是一个没有方向区分的图,这种图被称为无向图

图的表示

邻接矩阵

拥有n个顶点的图,它所包含的连接数量最多是n(n-1)个。因此,要表达各个顶点之间的关联关系,最清晰易懂的方式是使用二维数组(矩阵)。

具体如何表示呢?我们首先来看看无向图的矩阵表示:

如图所示,顶点0和顶点1之间有边关联,那么矩阵中的元素A[0][1]与A[1][0]的值就是1;顶点1和顶点2之间没有边关联,那么矩阵中的元素A[1][2]与A[2][1]的值就是0。

像这样表达图中顶点关联关系的矩阵,就叫做邻接矩阵

需要注意的是,矩阵从左上到右下的一条对角线,其上的元素值必然是0。这样很容易想明白:任何一个顶点与它自身是没有连接的。

同时,无向图对应的矩阵是一个对称矩阵,V0和V1有关联,那么V1和V0也必定有关联,因此A[0][1]和A[1][0]的值一定相等。

那么,有向图的邻接矩阵又是什么样子呢?

从图中可以看出,有向图不再是一个对称矩阵。从V0可以到达V1,从V1却未必能到达V0,因此A[0][1]和A[1][0]的值不一定相等。

邻接矩阵的优点是什么呢?简单直观,可以快速查到一个顶点和另一顶点之间的关联关系。

邻接矩阵的缺点是什么呢?占用了太多的空间。试想,如果一个图有1000个顶点,其中只有10个顶点之间有关联(这种情况叫做稀疏图),却不得不建立一个1000X1000的二维数组,实在太浪费了。

邻接表和逆邻接表

为了解决邻接矩阵占用空间的问题,人们想到了另一种图的表示方法:邻接表。

在邻接表中,图的每一个顶点都是一个链表的头节点,其后连接着该顶点能够直接达到的相邻顶点。

很明显,这种邻接表的存储方式,占用的空间比邻接矩阵要小得多。

要想查出从顶点0能否到达顶点1,该怎么做呢?很简单,我们从顶点0开始,顺着链表的头节点向后遍历,看看后继的节点中是否存在顶点1。

要想查出顶点0能够到达的所有相邻节点,也很简单,从顶点0向后的所有链表节点,就是顶点0能到达的相邻节点。

那么,要想查出有哪些节点能一步到达顶点1,又该怎么做呢?这样就麻烦一些了,我们要遍历每一个顶点所在的链表,看看链表节点中是否包含节点1,最后发现顶点0和顶点3可以到达顶点1。

像这种逆向查找的麻烦,该如何解决呢?我们可以是用逆邻接表来解决。

逆邻接表顾名思义,和邻接表是正好相反的。逆邻接表每一个顶点作为链表的头节点,后继节点所存储的是能够直接达到该顶点的相邻顶点。

这样一来,要想查出有哪些节点能一步到达顶点1就容易了,从顶点1向后的所有链表节点,就是能一步到达顶点1的节点。

因此,我们可以根据实际需求,选择使用邻接表还是逆邻接表。

十字链表

十字链表长什么样呢?用最直观的示意,是下面这样:

如图所示,十字链表的每一个顶点,都是两个链表的根节点,其中一个链表存储着该顶点能到达的相邻顶点,另一个链表存储着能到达该顶点的相邻节点。

不过,上图只是一个便于理解的示意图,我们没有必要把链表的节点都重复存储两次。在优化之后的十字链表中,链表的每一个节点不再是顶点,而是一条边,里面包含起止顶点的下标。

十字链表节点和边的对应关系,如下图所示:

因此,优化之后的十字链表,是下面这个样子:

图中每一条带有蓝色箭头的链表,存储着从顶点出发的边;每一条带有橙色箭头的链表,存储着进入顶点的边。初学十字链表的时候,可能会觉得有些乱。

总结

1.我们这一次介绍了图的定义和分类。根据图的边是否有方向,可分为有向图无向图。根据图的边是否有权重,可分为带权无权图。当然,也可以把两个维度结合起来描述,比如有向带权图,无向无权图等等。

2.图的表示方法有很多种。包括邻接矩阵、邻接表、逆邻接表、十字链表(还有一种邻接多重表,有兴趣的小伙伴可以自学下)。

声明:本文为作者投稿,版权归其个人所有。欢迎大家通过以下方式联系投稿。

【End】

 热 文 推 荐 

☞ 腾讯服务器崩溃!

5G 是未来的唯一选择?| 畅言

苹果新一代 AirPods 能活过两年吗?

☞ 18 岁少年盗取价值 90 万元的萌乃币, 交易所被迫关停!

李笑来登顶 GitHub TOP 榜!币圈大佬要教程序员如何自学编程

马云:蚂蚁金服这样做区块链!

女生适合做程序员吗?

Google首页玩起小游戏,AI作曲让你变身巴赫

曝光!月薪 5 万的程序员面试题:73% 人都做错,你敢试吗?

System.out.println("点个在看吧!");
console.log("点个在看吧!");
print("点个在看吧!");
printf("点个在看吧!\n");
cout << "点个在看吧!" << endl;
Console.WriteLine("点个在看吧!");
Response.Write("点个在看吧!");
alert("点个在看吧!")
echo "点个在好看吧!"

喜欢就点击“好看”吧!

漫画:为什么你需要了解数据结构中的图?相关推荐

  1. 数据结构中等号表示什么_通过分析2016年最重要的252个中等故事我学到了什么...

    数据结构中等号表示什么 Medium may be struggling to find a sustainable business model, but they have years worth ...

  2. 图解:数据结构中的6种「树」,柠檬问你心中有数吗?

    数据结构这门课程是计算机相关专业的基础课,数据结构指的是数据在计算机中的存储.组织方式. 我们在学习数据结构时候,会遇到各种各样的基础数据结构,比如堆栈.队列.数组.链表.树...这些基本的数据结构类 ...

  3. 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

    原文:http://blog.csdn.net/sup_heaven/article/details/39313731 数据结构中常见的树(BST二叉搜索树.AVL平衡二叉树.RBT红黑树.B-树.B ...

  4. gsoap中的数据结构中不允许有野指针

    2019独角兽企业重金招聘Python工程师标准>>> gsoap中的数据结构中不允许有野指针,比如char *p,没有给它赋值,就必须要给其赋值为NULL. 转载于:https:/ ...

  5. 数据结构——数据结构中的数据表示

    1,本文介绍数据的概念,以便讨论数据结构究竟是什么: 2,程序设计的挑战: 1,利用计算机解决现实生活中的问题: 1,计算机顾名思义是其诞生的时候仅仅是给科学家使用,科学家用计算机进行计算: 2,这是 ...

  6. c语言折半查找递归程序,C语言数据结构中二分查找递归非递归实现并分析

    C语言数据结构中二分查找递归非递归实现并分析 前言: 二分查找在有序数列的查找过程中算法复杂度低,并且效率很高.因此较为受我们追捧.其实二分查找算法,是一个很经典的算法.但是呢,又容易写错.因为总是考 ...

  7. [数据结构]数据结构中各种树

    阅读目录 1. 二叉树 2. 二叉查找树 3. 平衡二叉树 3.1 平衡查找树之AVL树 3.2 平衡二叉树之红黑树 4. B树 5. B+树 6. B*树 7. Trie树 数据结构中有很多树的结构 ...

  8. 初始化栈的代码_数据结构中的栈,你知道多少?

    由于栈比较简单,也很容易理解,学过的人都知道一句话就可以描述栈的特性:后进先出.所以这篇文章主要是写如何使用代码来描述栈,当然也是让大家很容易理解的语言.还是先给出这篇文章的大致脉络. 首先,对栈有一 ...

  9. 数据结构中的各种排序---总结篇

    转载:http://blog.csdn.net/wzyhb123456789/article/details/5974790 一个月没有写文章,原因是一直在忙碌着,但是其实是有收获的,下面就是我这前半 ...

最新文章

  1. 007.Adding a view to an ASP.NET Core MVC app -- 【在asp.net core mvc中添加视图】
  2. 重装华为服务器系统软件,服务器系统重装软件
  3. 第八周实践项目6 猴子选大王(数组版)
  4. zookeeper3.4.6安装
  5. python3精要(59)-转换
  6. JAVA中System.out.println和System.out.print有什么区别
  7. make: Nothing to be done for `first'
  8. POJ 1936 All in All
  9. horizon client 无法识别域_「领域驱动设计DDD」事件风暴简介:实现域驱动设计的简便方法...
  10. 玩转oracle 11g(44):数据库发展历史
  11. 从零开始编写自己的C#框架(7)——需求分析
  12. 医学方面的创业计划书_医学生创业计划书
  13. 怎么自己发表计算机学术论文,计算机学术论文写做与发表
  14. 激光雷达电力巡基于机载激光雷达技术的输电线路树障普查及预警
  15. 计算机三级要英语词汇,大学英语三级常考词汇
  16. Win7下载安装Mongodb教程
  17. matlab拟合多自变量函数,matlab曲线拟合公式中含有两个变量,x是自变量,y既是自变量又是因变量,求指导,y=f(x,y)...
  18. 硬盘安装linux镜像文件iso安装,通过ISO文件硬盘安装Ubuntu系统
  19. Excel中按多个符号进行分列
  20. 微信小程序开发—— app.json

热门文章

  1. java quickhit项目_【QuickHit项目实例】
  2. python 读取邮件内容_利用Python imaplib和email模块 读取邮件文本内容及附件内容...
  3. 【OpenCV】矩阵掩模操作
  4. Linux的iovec、readv和writev
  5. 2021年中国一次性防护服市场趋势报告、技术动态创新及2027年市场预测
  6. 车轮轴承行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  7. 2021年中国单硝酸异山梨酯市场趋势报告、技术动态创新及2027年市场预测
  8. 永中office属于职称计算机吗,2017职称计算机考试WPS_Office检测练习及答案13-中华考试网...
  9. JAVA Swing GUI设计 WindowBuilder Pro Container使用大全1——JTabbePane(卡片)使用
  10. 25% 的开发者认为 Rust 是最佳替代,最新 Go 开发者调查报告出炉