深度优先搜索(DFS)和广度优先搜索(BFS)

发布时间 2024-01-01 21:50:00作者: 李若盛开

深度优先搜索(DFS)和广度优先搜索(BFS),都是图形搜索算法,相似又却不同,在应用上也被用到不同的地方。

一、深度优先搜索(DFS)

深度优先搜索属于图算法的一种,是一个针对图和树的遍历算法,英文缩写为DFS即Depth First Search。深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。一般用栈stack数据结构来辅助实现DFS算法。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。
若将bfs策略应用于树结构,其效果等同与前中后序遍历。不管是前序遍历,还是中序遍历,亦或是后序遍历,都属于深度优先遍历。

深度优先遍历的思路是从图的一个未访问的顶点V开始,沿着一条路一直走到底,然后从这条路尽头的节点回退到上一个节点,再从另一条路开始走到底,不断递归重复此过程…直到所有的顶点都遍历完成。它的特点说通俗了就是不撞南墙不回头,走完了一条路,再换一条路继续走。

二、广度优先搜索(BFS)

广度优先搜索(也称宽度优先搜索,缩写BFS即即Breadth First Search)是连通图的一种遍历算法。这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和广度优先搜索类似的思想。其属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。基本过程,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。

广度优先遍历的思路,是从图的一个未遍历的节点出发,先遍历这个节点的相邻节点,再依次遍历每个相邻节点的相邻节点。

所采用的策略可概况为越早被访问到的顶点,其邻居顶点越早被访问。于是,从根顶点s的BFS搜索,将首先访问顶点s;再依次访问s所有尚未访问到的邻居;再按后者被访问的先后次序,逐个访问它们的邻居。一般用队列queue数据结构来辅助实现BFS算法。
若将bfs策略应用于树结构,其效果等同与层次遍历。

三、区别

1、如果扩展是首先扩展新产生的状态,则叫深度优先搜索。

如果搜索是以接近起始状态的程序依次扩展状态的,则叫广度优先搜索。
深度优先搜索:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次;
广度优先搜索:又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。
2、二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。
3、深度优先搜索:通常不全部保留结点,扩展完的结点从数据库中弹出删去,这样,一般在数据库中存储的结点数就是深度值,因此它占用空间较少。所以,当搜索树的结点较多,用其它方法易产生内存溢出时,深度优先搜索不失为一种有效的求解方法;  
广度优先搜索:一般需存储产生的所有结点,占用的存储空间要比深度优先搜索大得多,因此,程序设计中,必须考虑溢出和节省内存空间的问题,但广度优先搜索法一般无回溯操作,即入栈和出栈的操作,所以运行速度比深度优先搜索要快些。

四、总结

1)相同点:

深度优先遍历与广度优先遍历算法在时间复杂度上是一样的

2)不同点:

不同之处仅仅在于对顶点访问的顺序不同:

A:深度优先遍历
更适合目标比较明确,以找到目标为主要目的的情况。不全部保留节点,占用空间少,有回溯操作(即有入栈,出栈操作),运行速度慢。
B:广度优先遍历
更适合在不断扩大遍历范围时找到相对最优解的情况。保留全部节点,占用空间大,无回溯操作(即无入栈,出栈操作),运行速度快。