图论算法之DFS与BFS

  • 概述(总)

DFS是算法中图论部分中最基本的算法之一。对于算法入门者而言,这是一个必须掌握的基本算法。它的算法思想可以运用在很多地方,利用它可以解决很多实际问题,但是深入掌握其原理是我们灵活运用它的关键所在。

  • 含义特点

DFS即深度优先搜索,有点类似广度优先搜索,也是对一个连通图进行遍历的算法。它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念。

由于用到递归,当节点特别多且深度很大的时候,可能会发生栈溢出。解决办法是将递归改为非递归,自行编写栈。

BFS即广度优先搜索(也称宽度优先搜索),是连通图的一种遍历策略。因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名。 一般可以用它做什么呢?一个最直观经典的例子就是走迷宫,我们从起点开始,找出到终点的最短路程,很多最短路径算法就是基于广度优先的思想成立的。

  • 应用场景
  • dfs
  1. 连通分量

连通分量:任意两点可互达的图。

求无向图的连通分量:O(n)

  1. 二分图判定

二分图:每条边的两个节点分别着不同的两种颜色。

判断一个图是否是二分图:O(n)

  1. 二叉树的递归遍历
  • bfs
  1. 求割顶和桥

割顶:对于无向图G,如果删除某点u后,连通分量数目增加,则u即割顶。

桥:对于无向图G,如果删除某点边e后,连通分量数目增加,则e即桥。

求所有的图中的割顶和桥:

方式一:尝试删除每个节点,用dfs判断连通分量是否增加。时间复杂度:O(n(n+m))。

方式二:给每个节点记录两个时间戳,深入挖掘dfs。时间复杂度:O(n+m)。

  2.二叉树的层次遍历

  • 代码实现
/**
* DFS核心伪代码
* 前置条件是visit数组全部设置成false
* @param n 当前开始搜索的节点
* @param d 当前到达的深度
* @return 是否有解
*/
bool DFS(Node n, int d){
if (isEnd(n, d)){//一旦搜索深度到达一个结束状态,就返回true
return true;
}
for (Node nextNode in n){//遍历n相邻的节点nextNode
if (!visit[nextNode]){//
visit[nextNode] = true;//在下一步搜索中,nextNode不能再次出现
if (DFS(nextNode, d+1)){//如果搜索出有解
//做些其他事情,例如记录结果深度等
return true;
}
//重新设置成false,因为它有可能出现在下一次搜索的别的路径中
visit[nextNode] = false;
}
}
return false;//本次搜索无解
}
/**
* 广度优先搜索
* @param Vs 起点
* @param Vd 终点
*/
bool BFS(Node& Vs, Node& Vd){
queue<Node> Q;
Node Vn, Vw;
int i;

//初始状态将起点放进队列Q
Q.push(Vs);
hash(Vw) = true;//设置节点已经访问过了!

while (!Q.empty()){//队列不为空,继续搜索!
//取出队列的头Vn
Vn = Q.front();

//从队列中移除
Q.pop();

while(Vw = Vn通过某规则能够到达的节点){
if (Vw == Vd){//找到终点了!
//把路径记录,这里没给出解法
return true;//返回
}

if (isValid(Vw) && !visit[Vw]){
//Vw是一个合法的节点并且为白色节点
Q.push(Vw);//加入队列Q
hash(Vw) = true;//设置节点颜色
}
}
}
return false;//无解
}
  • 总结(总)
  • DFS适合此类题目:给定初始状态跟目标状态,要求判断从初始状态到目标状态是否有解。
  • BFS适合此类题目:给定初始状态跟目标状态,要求从初始状态到目标状态的最短路径。
  • 参考资料

http://rapheal.iteye.com/blog/1526863

http://blog.csdn.net/u011437229/article/details/53188837

http://www.cnblogs.com/George1994/p/6346751.html

时间: 2024-10-09 05:21:28

图论算法之DFS与BFS的相关文章

邻接表实现Dijkstra算法以及DFS与BFS算法

//============================================================================ // Name : ListDijkstra.cpp // Author : fffff // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //==========================

图的遍历算法:DFS、BFS

在图的基本算法中,最初需要接触的就是图的遍历算法,根据访问节点的顺序,可分为深度优先搜索(DFS)和广度优先搜索(BFS). DFS(深度优先搜索)算法 Depth-First-Search 深度优先算法,是一种用于遍历或搜索树或图的算法.沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点. 这一过程一直进行到已发现从源节点可达的所有节点为止. 如果还存在未被发现的节点, 则选择其中一个作为源节点并重复以上过程,整个进程反复

DFS,BFS算法

粗略的讲一下这两种算法,为老年痴呆做好准备(ノへ ̄.) DFS: 如上图,你将搜索整张图,而DFS的搜索方法就是,先一味的往前走!走到某个尽头后发现无路可走,后退.咦?后退一步有一个分岔口,这里有多个支路,选择一条没走过的继续走,碰到死胡同,后退,又到了这个分岔口,再去选择没走过的路,直到无路可走,然后返回上一个分岔口.具体过程如下:                                                                       (图中黑色数字均为遍历

图的遍历 (dfs与bfs)x

遍历是很多图论算法的基础,所谓图的遍历( graph traversal),也称为搜索( search),就是从图中某个顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次.         遍历可以采取两种方法进行:         深度优先搜索( DFS: depth first search):         广度优先搜索( BFS: breadth first search). 对图进行存储与遍历: 输入: 第一行:顶点数n. 第二行:边数m. 以下m行,每行两个顶点编号u

学习笔记:图的DFS和BFS的两种搜索办法

  在学习图结构的过程中,DFS和BFS是两种不同的遍历方式,其寻找元素具有不同的优点和缺陷. BFS被称作广度优先算法, 在遍历整个图的过程中,BFS将采用入队的方式进行,值得一提的是,这和树结构中的层序遍历有很大的相似之处. 在层序遍历中,将父亲节点入队后,在父亲节点出队后,将其儿子节点入队. 同理在图的BFS遍历中,先让BFS的首元素入队,在收元素入队后将他的儿子节点入队,放能够实现BFS搜索,他们的整体思想是一样的. 1 void TraversalGraph_BFS(LGraph Gr

图论算法之最短路径

图论算法之最短路径 作者:jasonkent27 转载请注明出处:www.cnblogs.com/jasonkent27 1. 前言 1.1 最短路引入 小明和小天现在住在海口(C1),他们俩计划暑假到三亚(C4)玩一趟,在海口和三亚之间有许多中间城市(文昌,临高,乐东,万宁...)图中的边上的数字是他们到达该城市必须的花费,现在需要你帮他们俩找出一条从海口到三亚的最省钱的路径出来. 等等,图中的边的weight怎么会有负的呢?你暂且可以这么理解吧.图中的边上的weight可以当作他们旅途中必须

图论算法----强连通

poj 2186 Popular Cows 分析:直接求一下强连通分量,对于同一个强连通分量里面的结点状态是相同的,要求有多少个人被其他所有的人都认可,只有可能是拓扑排序的最后一个强连通的结点个数,判断一下其他节点是否都可以到该联通分量就ok了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <set> 5 #include <algorithm>

图论算法(5) --- 双向广搜求最短路(Bidirectional Breadth First Search)

我们知道,在图论算法中,求最短路是最基本的问题.在求最短路的问题中,应用双向广度优先搜索算法,又是一个较为高效而又简单的算法.所谓双向广度优先搜索,其实根本的核心还是BFS,只不过它是从起点和终点两头同时搜索,大大提高了搜索效率,又节省了搜索空间.广搜大家知道当然是用队列来实现了,在这里,要注意的问题就是,我们必须按层搜索,正向队列处理一层,接着去处理反向队列的一层,按层交替进行,而不是按节点交替进行,这点需要注意,其他的也就很简单了,代码中附有注释,如有问题请留言. package simil

DFS 和BFS

DFS(Depth First Search) 深度优先搜索 BFS (Breadth First Search)宽度优先搜索 在算法中常用这两种方法. 1) DFS考虑用“递归”实现和用 “栈”实现两种方法,因为对于大型问题搜索深度比较深,如果用递归实现的话,栈空间占用比较多,递归调用需要的额外时间也比较多,容易超时,这时候就要考虑用栈模拟DFS的实现. 2) BFS用“队列”模拟来实现. DFS 和BFS