BFS DFS

BFS 和 DFS是简单且重要的图遍历算法。

BFS

距离d,BFS 可以计算出源节点S到任意可达节点的距离(一条简单路径,且经过的边数最少),或者说,在所有边的权重为1的情况下,源节点和任意可达节点的最短距离。
算法始终在发现节点和未发现节点之间扩展,总会先发现,距离源节点k的节点,然后发现距离源节点为k+1的节点。也就是说沿广度方向扩展。

伪代码

BFS(S)
    将除去源节点S以外的所有节点的到源节点距离d设为INF(无穷大),标记属性f为未发现。
    将源节点d设为0,f设为已发现。
    新建一个空队列q。
    将节点S放入队列q中。
    在队列不为空的情况下,重复一下操作:
            1.将队首元素u取出。
            2.将u的所有相邻且未发现节点距离d设为u.d + 1,f设为 已发现,并放入队列q中。
            3.返回操作1。

时间复杂度

对于图G(V,E),因为每条边被访问次数为O(1),每个节点入队和出队一次,时间复杂度为 O(1),总的复杂度 为O(V+E).

DFS

DFS在运行过程中,节点的首次发现时间u.sd和发现完成时间u.fd(发现完成:所有相邻接点均被发现)是比较有用的属性。
DFS总是沿着最近发现的节点进行探索,假设发现了节点u,并且节点u可达且未被发现的相邻接点为:v1,v2,v3,,vk.且从u出发访问的次序也是这个次序。
算法会先发现v1,然后将v1所有可达节点发现完毕后,算法会返回上一层到u,然后从v2开始,重复以上操作。

伪代码

DFS()
    将所有节点的标记属性f为未发现。
    全局属性时间 t = 0;
    对每一个未发现的节点u,然后,执行DFS_VISIT(u):

DFS_VISIT(s)
    将节点s的发现时间设为s.sd = ++t;
    属性f设为:已发现
    对节点s的所有未发现节点v执行DFS_VISIT(v);
    将节点s的发现完成时间s.fd = ++t;

时间复杂度

和BFS分析方法类似,可得:O(V+E);

应用

BFS,DFS是搜索常用的策略,根据需要进行属性的添加和删除,DFS还可以用于拓扑排序。

主要参考算法导论,如有错误,恳请指正。

猜你喜欢

转载自www.cnblogs.com/lif323/p/9417768.html