BFS和DFS的简要分析
2015-08-26 00:35
344 查看
广度优先搜索(BFS),可以被形象的描述为“浅尝辄止”,具体一点就是每个顶点只访问它的邻接节点(如果它的邻接节点没有被访问)并且记录这个邻接节点,当访问完它的邻接节点之后就结束这个顶点的访问。
广度优先用到了“先进先出”队列,通过这个队列来存储第一次发现的节点,以便下一次的处理;而对于再次发现的节点,我们不予理会——不放入队列,因为再次发现的节点:
无非是已经处理完的了;
或者是存储在队列中尚未处理的。
《算法导轮》对两种搜索都采用了很聪明的做法,用白色WHITE来标志未发现的节点,用灰色GRAY来标志第一次被发现的节点,用黑色BLACK来标志第二次被发现的节点。
于是有了:
导轮还在上面伪代码的“其他”中加入了访问长度和父节点的操作。此举可以算出,从源点到其他顶点路径的最少步数和它的具体路径。
关于广度优先搜索的一个简单应用:
假如有问题,每个村庄之间都通过桥来联通,先给出村庄的图,问村庄A到村庄B最少要通过多少座桥?这个问题可以很容易的转化为上面的BFS问题。
深度优先搜索(DFS),可以被形象的描述为“打破沙锅问到底”,具体一点就是访问一个顶点之后,我继而访问它的下一个邻接的顶点,如此往复,直到当前顶点一被访问或者它不存在邻接的顶点。
同样,算法导论采用了“聪明的做法”,用三种颜色来标记三种状态。但这三种状态不同于广度优先搜索:
WHITE 未访问顶点
GRAY 一条深度搜索路径上的顶点,即被发现时
BLACK 此顶点的邻接顶点被全部访问完之后——结束访问次顶点
通过给DFS搜索过程中给每一个顶点加时间戳,就可以实现拓扑排序了。实现拓扑排序需要:
对于每一个顶点,都有两个时间戳,分别这样来定义:
在一顶点刚被发现的时候,标记此顶点的第一个时间戳;
在结束此顶点的访问的时候,标记此顶点的第二个时间戳。时间戳可以用简单的123456来标记,只要能区分大小就行。
因此,你会发现,越早发现的点,他的第一个时间戳会越小,但是他的第二个时间戳会越大。
两个算法都是O(V+E),在用到的时候适当选取。在使用白灰黑标志的时候,突然明白了如何用深度优先搜索来判断有向图中是否存在环。
深度优先和广度优先各有各的优缺点:
广优的话,占内存多,能找到最优解,必须遍历所有分枝. 广优的一个应用就是迪科斯彻单元最短路径算法.
深优的话,占内存少,能找到最优解(一定条件下),但能很快找到接近解(优点),可能不必遍历所有分枝(也就是速度快), 深优的一个应用就是连连看游戏.
在更多的情况下,深优是比较好的方案。
广度优先用到了“先进先出”队列,通过这个队列来存储第一次发现的节点,以便下一次的处理;而对于再次发现的节点,我们不予理会——不放入队列,因为再次发现的节点:
无非是已经处理完的了;
或者是存储在队列中尚未处理的。
《算法导轮》对两种搜索都采用了很聪明的做法,用白色WHITE来标志未发现的节点,用灰色GRAY来标志第一次被发现的节点,用黑色BLACK来标志第二次被发现的节点。
于是有了:
关于广度优先搜索的一个简单应用:
假如有问题,每个村庄之间都通过桥来联通,先给出村庄的图,问村庄A到村庄B最少要通过多少座桥?这个问题可以很容易的转化为上面的BFS问题。
深度优先搜索
深度优先搜索(DFS),可以被形象的描述为“打破沙锅问到底”,具体一点就是访问一个顶点之后,我继而访问它的下一个邻接的顶点,如此往复,直到当前顶点一被访问或者它不存在邻接的顶点。同样,算法导论采用了“聪明的做法”,用三种颜色来标记三种状态。但这三种状态不同于广度优先搜索:
WHITE 未访问顶点
GRAY 一条深度搜索路径上的顶点,即被发现时
BLACK 此顶点的邻接顶点被全部访问完之后——结束访问次顶点
通过给DFS搜索过程中给每一个顶点加时间戳,就可以实现拓扑排序了。实现拓扑排序需要:
对于每一个顶点,都有两个时间戳,分别这样来定义:
在一顶点刚被发现的时候,标记此顶点的第一个时间戳;
在结束此顶点的访问的时候,标记此顶点的第二个时间戳。时间戳可以用简单的123456来标记,只要能区分大小就行。
因此,你会发现,越早发现的点,他的第一个时间戳会越小,但是他的第二个时间戳会越大。
总结
两个算法都是O(V+E),在用到的时候适当选取。在使用白灰黑标志的时候,突然明白了如何用深度优先搜索来判断有向图中是否存在环。深度优先和广度优先各有各的优缺点:
广优的话,占内存多,能找到最优解,必须遍历所有分枝. 广优的一个应用就是迪科斯彻单元最短路径算法.
深优的话,占内存少,能找到最优解(一定条件下),但能很快找到接近解(优点),可能不必遍历所有分枝(也就是速度快), 深优的一个应用就是连连看游戏.
在更多的情况下,深优是比较好的方案。
相关文章推荐
- Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感 是印度上古时期一些文献的总称
- docker学习笔记3—使用Dockerfile与docker build命令创建一个nginx服务器镜像,并使用浏览器进行访问
- 开发中最常用的GitHub上 优秀的 Android 开源项目整理
- Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感 是印度上古时期一些文献的总称
- atitit.薄伽梵歌overview attilax 读后感
- Filter过滤器实现自动登录
- 静态库 动态库
- 【Zookeeper】研究Zookeeper
- 设计模式在游戏中的应用--外观模式(八)
- 对“仅通过崩溃地址找出源代码的出错行”一文的补充与改进
- Qt 利用QSettings + config.ini 保存设置
- Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
- HDU 4119 Isabella's Message (2011年成都赛区现场赛I题)
- 弹出窗口
- Android在同一个活动中加载两个布局,一个是XML还有个是draw(即自己用画布画的)
- 仅通过崩溃地址找出源代码的出错行
- 第一百四十五天 how can I 坚持
- C++ Primer : 第十二章 : 动态内存之shared_ptr与new的结合使用、智能指针异常
- 以Oracle数据库为目标的数据库进阶(三、四)
- bzoj 2744: [HEOI2012]朋友圈 二分图匹配