如何理解图
和树比起来是一种更加复杂的非线性表结构。
树中的元素我们称为节点,图中的元素我们叫做顶点
在这里插入图片描述
从图中可以看出来,图中的一个顶点可以与任意其他顶点建立连接关系。我们把这种建立的关系叫做
顶点的:与顶点相连的边的条数。
比如微信,我们可以把每个用户看作一个顶点。如果两个用户之间互加好友,那就在两者之间建立一条边。所以,整个微信的好友关系就可以用一张图来表示。其中,每个用户有多少个好友,对应到图中,就是顶点的度。

边有方向的图叫做有向图,边没有方向的图叫做无向图。

在这里插入图片描述
在有向图中我们把度分为入度(In-degree)和出度(Out-degree)。
顶点的入度,表示有多少条边指向这个顶点;顶点的出度,表示有多少条边是以这个顶点为起点指向其他顶点。
对应到微博的例子,入度就表示有多少粉丝,出度就表示关注了多少人。

带权图,在带权图中,每条边都有一个权重,例如QQ中的亲密度这一功能,我们可以通过这个权重来表示QQ好友间的亲密度。
在这里插入图片描述
如何在内存中存储图这一数据结构呢?
邻接矩阵存储方法
图最直观的一种存储方法就是,邻接矩阵。
邻接矩阵的底层依赖一个二维数组。
对于无向图来说,如果顶点i与j之间有边,我们就将A[i][j]和A[j][i]标记为1;对于有向图来说,如果顶点i到顶点j之间,有一条箭头从顶点i指向顶点j的边,那我们就将A[i][j]标记为1。同理,如果有一条箭头从顶点j指向顶点i的边,我们就将A[j][i]标记为1。对于带权图,数组中就存储相应的权重。
在这里插入图片描述
缺点:
比较浪费存储空间。
比如,对于无向图来说,如果A[i][j]等于1,那么A[j][i]也肯定等于1。实际上,我们只需要存储一个就可以了。
还有,如果我们存储的是稀疏图,即顶点很多,但每个顶点的边并不多,那邻接矩阵的存储方法就更加浪费空间了。
优点:
首先,邻接矩阵的存储方式简单、直接,因为基于数组,所以在获取两个顶点的关系时,就非常高效。
其次,用邻接矩阵存储图,可以将很多图的运算转换成矩阵之间的运算。

邻接表存储方法
在这里插入图片描述
乍一看,邻接表挺像散列表的,每个顶点对应一条链表,链表中存储的是与这个顶点相连接的其他顶点。上图中画的是一个有向图的邻接表存储方式,每个顶点对应的链表里面,存储的是指向的顶点。对于无向图来说,每个顶点的链表中存储的是跟这个顶点有边相连的顶点。

邻接矩阵存储起来比较浪费空间,但是使用起来比较节省时间。相反,邻接表存储起来比较节省空间,但是使用起来就比较耗费时间。
邻接表的改进版,即将链表换成更加高效的动态数据结构,比如平衡二叉查找树,跳表,散列表等。

逆邻接表
邻接表中存储用户的关注关系,逆邻接表中存储的是用户的被关注关系。逆邻接表中,每个顶点的链表中存储的是指向这个顶点的顶点。
在这里插入图片描述
算法是作用于具体数据结构之上的,深度优先搜索算法和广度优先搜索算法都是基于‘图’这种数据结构的。这是因为,图这种数据结构的表达能力很强,大部分涉及搜索的场景都可以抽象成‘图’。
广度优先搜索(BFS)
直观地讲,它其实就是一种“地毯式”层层推进的搜索策略,即先查找离起始顶点最近的,依次往外搜索。如下图所示:
在这里插入图片描述
广度优先搜索的分解图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述最坏情况下,终止顶点t离起始顶点s很远,需要遍历完整个图才能找到。这个时候,每个顶点都要进出一遍队列,每个边也都会被访问一次,所以,广度优先搜索的时间复杂度是O(V+E),其中,V表示顶点的个数,E表示边的个数。
对于一个连通图(一个图中的所有顶点都是连通的)来说,E肯定要大于等于V-1,所以,广度优先搜索的时间复杂度也可以简写为O(E)。
广度优先搜索的空间复杂度是O(V)。

深度优先搜索(DFS)
最直观的例子就是“走迷宫”。假设你站在迷宫的某个岔路口,然后想找到出口。你随意选择一个岔路口来走,走着走着发现走不通的时候,你就回退到上一个岔路口,重新选择一条路继续走,直到最终找到出口。这种走法就是一种深度优先搜索策略。
如何在图中应用深度优先搜索,来找某个顶点到另一个顶点的路径,整个搜索路径如下图所示:

在这里插入图片描述
图中实现箭头表示遍历,虚线箭头表示回退。从图中可以看出,深度优先搜索找出来的路径,并不是顶点s到顶点t的最短路径。
实际上,深度优先搜索用的是一种比较著名的算法思想,回溯思想。这种思想解决问题的过程,非常适合用递归来实现。
从上图可以看出,每条边最多会被访问两次,一次是遍历,一次是回退。所以,深度优先搜索算法的时间复杂度是O(E),E表示边的个数。空间复杂度是O(V)。

总结
广度优先搜索需要借助队列来实现,遍历得到的路径就是起始顶点到终止顶点的最短路径。
深度优先搜索是借助栈来实现的。
在执行效率方面,深度优先搜索和广度优先搜索的时间复杂度都是O(E),空间复杂度是O(V)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值