算法导论读书笔记(22)基本的图算法

来源:互联网 发布:手机没有usb共享网络 编辑:程序博客网 时间:2024/05/21 06:51

第六部分 图算法

第22章 基本的图算法

图的搜索指的系统化地跟随图中的边来访问图中的每个结点
搜索算法可以用来发现图的结构
图的两种表示法分别是邻接链表邻接矩阵

1. 图的表示

对于图G=(V, E)可以用两种标准表示方法表示:
1. 邻接链表,因为在表示稀疏图(边的条数|E|远远小于|V|^2的图)时非常紧凑而成为通常的选择。
2. 邻接矩阵,在稠密图(|E|接近|V|^2的图)的情况下,倾向于该表示法。

邻接链表表示一个包含|V|条链表的数组Adj所构成每个结点一条链表。对于每个结点,邻接链表Adj[u]包含所有与结点u之间有边相连的结点v,即Adj[u]包含图G中所有与u邻接的结点。
这里写图片描述

这里写图片描述

权重图是图中的每条边都带有一个相关的权重的图对邻接链表稍加修改,即可用来表示权重图

邻接链表的一个潜在缺陷无法快速判断一条边(u, v)是否是图中的一条边邻接矩阵克服了这个缺陷,但付出的代价是更大的存储空间消耗。邻接矩阵的空间需求皆为θ(V^2)

无向图的邻接矩阵是一个对称矩阵

邻接矩阵表示法更为简单,因此在图规模比较小时,我们可能更倾向于使用邻接矩阵表示法。

2.广度优先搜索

该搜索算法是许多重要的图算法的原型。Prim的最小生成树算法和Dijkstra的单源最短路径算法都使用了类似广度优先搜索的思想。

在广度优先搜索树里从结点s到结点v的简单路径所对应的就是图G中从结点s到结点v的“最短路径”。该算法既用于有向图,也可以用于无向图

广度优先搜索算法需要在发现所有距离源结点s为k的所有结点之后才会发现距离源结点s为k+1的其他结点

这里写图片描述

u.d记录的是广度优先搜索算法所计算出的从源点s到结点u之间的距离
u.π记录u的前驱结点

BFS(G, s)    for each vertex u∈G.V - {s}        u.color = White        u.d = ∞        d.π = NIL    s.color = Gray    u.d = 0    d.π = NIL    Q = ∅    EnQueue(Q, s)    while Q != ∅        u = DeQueue(Q)        for each v∈G.Adj[u]            if v.color == White                v.color = Gray                v.d = u.d + 1                v.π = u                EnQueue(Q, v)        u.color = Black

3.深度优先搜索

深度优先搜索总是对最近才发现的结点v出发边进行探索直到该结点的所有出发边都被发现为止一旦结点v的所有出发边都被发现,搜索则“回溯”到v的前驱结点,来搜索前驱结点的出发边

广度优先搜索的前驱子图形成一棵树,而深度优先搜索的前驱子图可能由多棵树组成

深度优先搜索的前驱子图形成一个由多棵深度优先树构成的深度优先森林。森林Eπ中的边仍然称为树边。

这里写图片描述
这里写图片描述

DFS(G)    for each vertex u∈G.V        u.color = White        u.π = NIL    time = 0    for each vertex u∈G.V        if u.color == White            DFS-Visit(G, u)
DFS-Visit(G, u)    time = time + 1         // white vertex u has just been discovered    u.d = time    u.color = Gray    for each v∈G.Adj[u]     // explore edge(u, v)        if v.color == White            v.π = u            DFS-Visit(G, v)    u.color = Black         // black u, it is finished    time = time + 1    u.f = time

深度优先搜索算法的运行时间为θ(V+E)。

深度优先搜索的性质

最基本的性质是,其生成的前驱子图Gπ形成一个由多棵树所构成的森林。
另一个重要性质是,结点的发现时间和完成时间具有所谓的括号化结构。

边的分类

深度优先搜索的另一个有趣的性质是,可以通过搜索来对输入图G=(V, E)的边进行分类:
1. 树边:为深度优先森林Gπ中的边。如果结点v是因算法对边(u, v)的探索而首先被发现,则(u, v)是一条树边。
2. 后向边:后向边(u, v)是将结点u连接到其在深度优先树中(一个)祖先结点v的边。由于有向图中可以有自循环,自循环也被认为是后向边。
3. 前向边:是将结点u连接到其在深度优先树中一个后代结点v的边(u, v)。
4. 横向边:指其他所有的边。

4. 拓扑排序

对于一个有向无环图G = (V,E)来说,其拓扑排序是G中所有结点的一种线性次序,该次序满足如下条件:如果图G包含边(u, v),则结点u在拓扑排序中处于结点v的前面。

拓扑排序就是将节点按完成时间进行降序排序。

这里写图片描述

Topological-Sort(G)    call DFS(G) to compute finishing times v.f for each vertex v as each vertex is finished, insert it onto the front of a linked list    return  the linked list of vertices

5. 强连通分量

如果一个无向图中每个顶点从所有其他顶点都是可达的,则称该图是连通的。图的连通分量是顶点在“从……可达”关系下的等价类。
如果一个有向图中任意两个顶点互相可达,则该有向图是强连通的。
这里写图片描述

Strongly-Connected-Components(G)    call DFS(G) to compute finishing times u.f for each vertex u    compute GT    call DFS(GT), but in the main loop of DFS, consider the vertices in order of decreasing u.f(as computed in line 1)    output the vertices of each tree in the depth-frist forest formed in line3 as a separate strongly connected component
原创粉丝点击