图之二(图的基本算法)

 1.        图的存储表示

1.1.       邻接表表示法

对图中每个顶点,维护一个以该顶点为起点的终点的链表。

整个图需要|V|条链表。邻接表即为这|V|条链表组成的表。

场景:一般用于稀疏表。

优点:

Ø  有向图中,所有邻接表的链长度和为|E|;无向图中,所有邻接表的链长度和为2*|E|.

Ø  每条链表的存储顺序没有要求。

Ø  邻接表表示法中,存储空间为O(V+E)。

Ø  邻接表也可以用于表示带权图,只要将权重存储在链表的顶点v的卫星数据中即可。

缺点:

Ø  要判断一条边(u,v)是否在图中,则需要遍历顶点u的链表。

1.2.       邻接矩阵表示法

为了快速的判断一条边(u,v)是否在图中,可以使用邻接矩阵表示法。

图的邻接矩阵表示法中,将顶点进行编号1.2….|V|。则图G的邻接矩阵A为

|V|*|V|矩阵aij=1,如果边(i,j)存在,aij=0,如果边(i,j)不存在。

特点:

Ø  存储空间为O(|V|*|V|),只与顶点有关,与边无关。

Ø  无向图中邻接矩阵为对称矩阵。因此存储空间可以减少一半。

Ø  如果以aij表示带权图的权,则也可以表示带权图。如果边不存在,则以无穷大表示。

2.        图的搜索

图的搜索是指有序的沿着图的边访问所有顶点。

2.1.       广度优先搜索(BFS)

给定图G=(V,E)及任意一个源顶点s,广度优先搜索系统地搜索图G中的边,以便“发现”可以从s到达的所有顶点,并计算s到达这些顶点的距离(最少的边数)。

该算法还能生成一颗以s为根,且包含s可达的所有顶点的一颗广度优先树

从s可达的任何顶点v,广度优先树中,从s到v的路径对应于图G中从s到v的一条最短路径。(对有向图,无向图都一样)。

算法称为广度优先的原因在于,算法始终以已发现、未发现顶点之间的边界,沿着广度方向向外发展。即算法会先发现与s相距为k的所有顶点,再发现距离为k+1的所有顶点。

广度优先搜索中,对顶点标以不同的颜色:白色、灰色、黑色

白色表示未发现的点,灰色、黑色都是已经发现的点,区别在于黑色表示其相邻顶点都已发现,但灰色顶点可能还有未发现的邻接点。即灰色代表了已发现和未发现的边界。

      广度搜索构造了一颗广度优先树。最开始只包含根,即源顶点s。在扫描已发现的顶点u时,如果发现一个白色顶点v,则将该顶点v以及边(u,v)添加到树中。称u为v的父节点。

      使用邻接表表示法时,广度优先搜索可以更快。因为和已发现顶点u的邻接点在其邻接链表中。

      对每个顶点,定义color域代表颜色,定义p域代表父节点,定义d域代表和源顶点s的距离。

      算法中使用一个优先队列(先进先出队列)管理灰色顶点,使用个迭代循环完成

      算法循环从队列中取顶点u,并从u的邻接表中取邻接顶点,如果邻接顶点为白色,则代表新发现,因此置为灰色。计算其d,p域,并入队列。链表处理完后,将u置为黑色。

      循环直到队列中无灰色元素为止

复杂度:为O(V+E)。

灰色队列中,任何时刻,队头的元素的d域最多比队尾的d域小1,且队列中的d域为非递减的

广度优先树也称作前驱子图。在搜索的时候即可建立。

扩展:

BFS搜索时,如果图以邻接矩阵表示。如何进行搜索?复杂度是多少?

树的直径:表示为树中所有最短路径的最大值。求树的直径。

2.2.       深度优先(DFS)

深度优先算法是尽可能“深”的搜索一个图。在深度优先算法中,对于新发现的顶点v,如果还有以此顶点v为起点的边,就沿着边继续探测下去。当该顶点v的所有边都探测完后,再回到发现顶点v的边的起始点。重复过程,直到从源顶点可达的所有顶点都被访问。如果此时还有未发现顶点,则选择一个为源顶点,重复这个过程,直到所有顶点都被访问这是和广度优先算法的不同点,这个不同的设计主要在于这两种算法的用法不同,广度优先一般用于查找最短路径,深度优先一般作为一个子程序,用于在图中遍历所有节点,以便进行别的操作。

      因此,深度优先遍历出来的是深度优先森林,与广度优先树不同,深度优先森林。

      深度优先的做法也是对顶点进行标色,标色方法和广度类似。且一般再对每个顶点标上两个时间,顶点v被发现的时间d(v)(变灰的时间),以及对v为根的树完成搜索的时间f(v)(变黑的时间)。因此在d(v)前,v为白色,d(v)和f(v)之间为灰色,f(v)后为黑色。

      算法对图进行遍历,先初始化,将所有顶点标识为白色,且父为空。对每个顶点,如果为白色则深度优先访问该顶点。

       深度优先访问顶点时,先将顶点值灰,并设置d(v),再对v的邻接点进行遍历,如果发现一个白色(未访问的顶点),则设置其父信息,并先递归对邻接的进行访问。当所有邻接点都访问完后,再将v置为黑色,并设置f(v)。递归为尾递归,因此可以用一个栈来消掉递归调用

      复杂度:也为O(V+E)

深度优先性质:

Ø  (括号定理)由[d(v),f(v)]组成的时间戳满足三分关系:两个时间的时间戳不相交,这时候这两个顶点u,v在深度优先森林中都不是对方的后裔。u的时间戳包含v的,则u为v的父。v的时间戳包含u的,则v为u的父。

Ø  (后裔嵌套)顶点u为v的父,当且仅当u时间戳包含v的时间戳。

Ø  (白色定理)顶点u为v的父,当且仅当在d(u)时刻发现u时,可以从u出发,经过由白色顶点组成的路径到达v。

深度优先树中边的分类:

Ø  树边:深度优先森林中,顶点v是在搜索边(u,v)时发现的,则(u,v)即为树边。

Ø  反向边:深度优先森林中,连接顶点u到其某一祖先(非父)顶点的边。有向图中的自环也是反向边。

Ø  正向边:顶点u与其后裔v的非树边(即u与孙节点v以及孙孙节点的边)。

Ø  交叉边:深度优先森林中,同一颗树中,一个顶点不是另一个顶点的祖先。或者不同树的顶点之间的边。

DFS入度非0的顶点开始访问时,d,f的关系不再成立,森林也有问题,拓扑排序也有问题?

2.3.       拓扑排序

有向无环图才能进行拓扑排序。否则不能排序。

是否可以拓扑排序:有向图无回路,当且仅当深度优先搜索时,无反向边则可以拓扑排序。

拓扑排序方法

方法一,使用深度优先搜索,并在完成搜索后,将顶点插入到一个链表的头部,搜索完成后,链表即为拓扑排序的结果。

方法二,找入度为0的顶点,删除顶点以及边;循环找入度为0的并删除顶点即边,直到无顶点。(生成树为一棵树的图可行,关系的保留问题。多生成树时的处理。)

2.4.       强连通分支

连通图:无向图,且任何两个顶点之间都“可达”,不需要直接可达。

连通分量:无向图的极大连通子图。

无向图连通分量,通过图的遍历即可求解。

强连通图:有向图,且任何两个顶点之间都“可达”,不需要直接可达。

强连通分量:有向图的极大强连通子图。

图的转置图。

强连通分量为图和转置图中都互相可达。

有向图强连通分量,通过遍历两遍,一遍为图,一遍为转置图。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值