NTU课程:MAS714 (3)Graph Algorithms

1 图(graph)的定义

 

 2 图的表示

2.1 邻接矩阵

2.1.1 邻接矩阵的优点

        在O(1)的时间复杂度下,就可以判断一条边(u,v)是否存在(直接看第u行第v列那个元素即可)

        可以做关于矩阵的代数运算

2.1.2 邻接矩阵的缺点

        需要Ω(n^2)的空间

       不能很高效地看一个点所有的邻边(需要找到这个点所在的一行/一列,然后遍历这一行/这一列),差不多需要O(n)的时间复杂度

2.2 邻接列表

邻接列表的每一个条目里是所有和点v相连的点 组成的列表

2.2.1 邻接列表的优点

        弥补了邻接矩阵所有的缺点:

        可以很方便地查看一个点所有的邻边(O(1)时间复杂度)

        空间复杂度O(n+m),m是图G的边数。

        对每一条边(a,b),我会在两个地方存储他的端点。adj[a]=b,adj[b]=a

        也就是说,如果我们有m条边,那我们需要O(m)的空间复杂度

        再加上adj的n个条目

        所以空间复杂度为O(m+n)

2.2.2 邻接列表的缺点

        基本上邻接矩阵的优点就是它的缺点

        判断两个点之间(eg,v&u)有没有边,需要遍历整个adj[v]中有没有u,这个需要O(n)的时间复杂度

2.3 邻接矩阵和邻接列表的权衡

        两种各有利弊,好处坏处互补。我们需要根据实际应用的需求来决定使用那种图的表示方法(eg,图是否稀疏?是否需要频繁找边?)

        在现实世界中,由于graph偏稀疏(sparse),同时  不一定有足够的空间来保存邻接矩阵。因此,邻接列表的使用更多一点。 

3 连接性

3.1 概念

3.1.1 path

 3.1.2 circle

3.1.3 连通图

 

3.1.4 连通部分

3.1.5 强连通性

3.2 树

3.2.1 树的性质

  1. 一个有n个节点的树有n-1条边
  2. 两个点之间的路径是唯一的

比如在一棵树上,我们有不同的两个路径 A-B-C和A-D-C,那么我们就会成环A-B-C-D-A,与无环冲突

 4 图的遍历

 找出所有和u有路径的点

 4.1 最naive的方法

        一开始只有一个节点(初始节点)被标记了(visited)

        每次遍历所有的边,看是不是一个顶点是visited另一个节点是unvisited,如果是的话,将不是unvisited的节点标记为visited

         重复上一步,直到找不到这样的边为止

        那么结束循环时候的节点就是所有u可以到达的节点

4.1.1 时间复杂度

        我们一步一步看

        第一步:——时间复杂度 O(n) 

        第二步: ——时间复杂度O(1)

        第三步:

                每一次循环,我们至少可以把一个点标记成visited,所以一共有O(n)次循环(n是图中点的数量)【可能比O(n)少,因为可能一次标记多个点,或者没有等所有的点标记完,就已经结束循环了】

                每一次循环内部,我们需要遍历所有的边,看看是不是这条边一个节点是visited另一个节点是unvisited,那么每一次循环,需要O(m)的时间复杂度(m是图中边的数量)

                ——所以第三步的时间复杂度是O(nm)

        因为O(n)肯定比O(nm)小,所以最终总的算法的时间复杂度是O(nm)  

4.2 改进方法

 

        4.1的naive方法中,我们有很多次重复地讨论了边的情况,比如如果一条边的两个节点都是visited或者都是unvisited,那么在这一轮循环中,我们理论上是可以不用讨论的,但是4.1的方法中也讨论了。4.2就尝试了去解决边遍历时候的冗余 

         我们设置了一个集合u,一开始只有初始节点u。

        每次从集合中取出一个点,找它的邻边中另外一个节点是unvisted的点。然后将那些点设置为visited,同时将那些点放入这个集合中。

        这样循环,直到集合空为止(可能是所有的点都遍历了,可能是剩余的点都不和标记为visited的点有邻边了)

4.2.1 时间复杂度

        第一步:——时间复杂度O(1)

        第二步:——时间复杂度O(n)

        第三步:——时间复杂度O(1)

        第四步:‘        

                这个循环怎么看呢?我们这样想:

                每一条图中的边最多被考虑两次。(如果一个节点是u的话,只考虑一次)

                一次是边的两个点都是unvisited的时候,如果本轮从R中取出来的点正好和这两个unvisited的点中的一个有连接。那么这个unvisited的点会被设置为visited,并放入R中,下次这个点被拿出来的时候,这条边会被遍历第一次。

                第二次就是上一步设置为visited的点,从R中拿出来,并遍历它的邻边的时候,会把这条边的第二个点设置为visited,并放入集合中。那么下次这第二个点被从R中拿出来的时候,这条边又会被遍历一次。(不过由于那个时候这条边的两个点都是visited了,所以不会有任何操作)

                所以第四步的时间复杂度是O(m)(m是图的边数量)

        所以总的时间复杂度是O(n+m)

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UQI-LIUWJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值