BFS和DFS的简要分析

广度优先搜索(BFS),可以被形象的描述为“浅尝辄止”,具体一点就是每个顶点只访问它的邻接节点(如果它的邻接节点没有被访问)并且记录这个邻接节点,当访问完它的邻接节点之后就结束这个顶点的访问。

广度优先用到了“先进先出”队列,通过这个队列来存储第一次发现的节点,以便下一次的处理;而对于再次发现的节点,我们不予理会——不放入队列,因为再次发现的节点:

  1. 无非是已经处理完的了;
  2. 或者是存储在队列中尚未处理的。

《算法导轮》对两种搜索都采用了很聪明的做法,用白色WHITE来标志未发现的节点,用灰色GRAY来标志第一次被发现的节点,用黑色BLACK来标志第二次被发现的节点。

于是有了:

BFS(G,s)

    for each
vertex v in V[G]

        status[v]
= WHITE

        /******其他初始化******/

    status[s]
= GRAY   
//s是原点

    queue
q

    入队(q,s);

    while q非空

        t
= 出队(q);

        for each
vertex v in Adj[t]
//与t邻接的点

            if status[v]
= WHITE   
//只对未访问的操作

                status[v]
= GRAY   
//标记为第一次访问

                /******其他操作******/

                入队(q,v)

        status[t]
= BLACK  
//此点已经处理完了

导轮还在上面伪代码的“其他”中加入了访问长度和父节点的操作。此举可以算出,从源点到其他顶点路径的最少步数和它的具体路径。

关于广度优先搜索的一个简单应用:

假如有问题,每个村庄之间都通过桥来联通,先给出村庄的图,问村庄A到村庄B最少要通过多少座桥?这个问题可以很容易的转化为上面的BFS问题。

深度优先搜索

深度优先搜索(DFS),可以被形象的描述为“打破沙锅问到底”,具体一点就是访问一个顶点之后,我继而访问它的下一个邻接的顶点,如此往复,直到当前顶点一被访问或者它不存在邻接的顶点。

同样,算法导论采用了“聪明的做法”,用三种颜色来标记三种状态。但这三种状态不同于广度优先搜索:

  1. WHITE 未访问顶点
  2. GRAY 一条深度搜索路径上的顶点,即被发现时
  3. BLACK 此顶点的邻接顶点被全部访问完之后——结束访问次顶点

DFS(G,s)

    for each
vertex v in V(G)

        status[v]
= WHITE

        /******其他初始化******/

    for each
vertex v in V(G)

        if(status[v]==WHITE)

            DFS-VISIT(v)

DFS-VISIT(v)

    status[v]
= GRAY

    for each
vertex t in Adj(v)

        if status[t]
= WHITE

            DFS-VISIT(t)

            /******其他操作******/

    status[v]
= BLACK

通过给DFS搜索过程中给每一个顶点加时间戳,就可以实现拓扑排序了。实现拓扑排序需要:

对于每一个顶点,都有两个时间戳,分别这样来定义:

  1. 在一顶点刚被发现的时候,标记此顶点的第一个时间戳;
  2. 在结束此顶点的访问的时候,标记此顶点的第二个时间戳。时间戳可以用简单的123456来标记,只要能区分大小就行。

因此,你会发现,越早发现的点,他的第一个时间戳会越小,但是他的第二个时间戳会越大。

总结

两个算法都是O(V+E),在用到的时候适当选取。在使用白灰黑标志的时候,突然明白了如何用深度优先搜索来判断有向图中是否存在环。

深度优先和广度优先各有各的优缺点:

  • 广优的话,占内存多,能找到最优解,必须遍历所有分枝. 广优的一个应用就是迪科斯彻单元最短路径算法.
  • 深优的话,占内存少,能找到最优解(一定条件下),但能很快找到接近解(优点),可能不必遍历所有分枝(也就是速度快), 深优的一个应用就是连连看游戏.

在更多的情况下,深优是比较好的方案。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-18 06:39:50

BFS和DFS的简要分析的相关文章

PAT Advanced 1034 Head of a Gang (30) [图的遍历,BFS,DFS,并查集]

题目 One way that the police finds the head of a gang is to check people's phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls mad

[Algorithms] Graph Traversal (BFS and DFS)

Graph is an important data structure and has many important applications. Moreover, grach traversal is key to many graph algorithms. There are two systematic ways to traverse a graph, breadth-first search (BFS) and depth-frist search (DFS). Before fo

loosejar原理简要分析

loosejar这个小工具可以动态分析出应用中有每个jar包的实际使用情况,详情请参阅<通过loosejar清理应用中冗余的jar包>基本原理是利用instrumentation的特性用 Instrumentation,开发者可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在 JVM 上的程序,甚至能够替换和修改某些类的定义.有了这样的功能,开发者就可以实现更为灵活的运行时虚拟机监控和 Java 类操作了.关于instrumentation的详细介绍,可以参阅这篇文章&l

intel万兆网卡驱动简要分析

原创文章,转载请注明: 转载自pagefault 本文链接地址: intel万兆网卡驱动简要分析 这里分析的驱动代码是给予linux kernel 3.4.4 对应的文件在drivers/net/ethernet/intel 目录下,这个分析不涉及到很细节的地方,主要目的是理解下数据在协议栈和驱动之间是如何交互的. 首先我们知道网卡都是pci设备,因此这里每个网卡驱动其实就是一个pci驱动.并且intel这里是把好几个万兆网卡(82599/82598/x540)的驱动做在一起的. 首先我们来看对

ECMall注册机制简要分析

ecmall的注册流程index.php?app=member&act=register. 首先app是member,act是register方法. index.php中.通过ecmall的startup方法来启动,主要包含了eccore/ecmall.php,startup方法中包含eccore/controller/app.base.php和eccore/model/model.base.php基础类,通过 1 $app = isset($_REQUEST['app']) ? trim($_

HDU 2102 A计划 (BFS或DFS)

题意:中文题. 析:是一个简单的搜索,BFS 和 DFS都可行, 主要是这个题有一个坑点,那就是如果有一层是#,另一个层是#或者*,都是过不去的,就可以直接路过, 剩下的就是一个简单的搜索,只不过是两层而已,可能一个就是在#必须传送,这个题目已经说的很清楚了. 代码如下: BFS: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string>

u-boot学习(二):u-boot简要分析

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 看到不错的文章,不要添加收藏夹,想着以后有时间再看,因为很有可能你以后再也不会看它们了. 想写总结的文章,不要想着等到以后有时间了再总结,因为很有可能你以后更没有时间总结它们了. --送给自己 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Android 4.4 Kitkat 音频实现及简要分析

在 Android 4.4 上实现录放音 背景 Android 自 ICS 开始,音频系统就有了很大的变化,先是抛弃了 alsalib,然后是采用了 AIO,各级框架上,都有了自己的特色,与 Linux 的音频应用渐行渐远,形成了自己独特的音频管理和音频配置功能.总的来说改进还是非常大,至少在用户体验上已经大大的超越了之前的版本.我们就从 4.4 的音频实现上来分析其中的一些变化和实现机制. 要求 首先是硬件功能正常,这个不表. Linux 支持 alsa 驱动,生成 alsa 子系统,最好是能

zoj 3811 Untrusted Patrol(bfs或dfs)

Untrusted Patrol Time Limit: 3 Seconds      Memory Limit: 65536 KB Edward is a rich man. He owns a large factory for health drink production. As a matter of course, there is a large warehouse in the factory. To ensure the safety of drinks, Edward hir