简述深度优先搜索
Posted Cristime 的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简述深度优先搜索相关的知识,希望对你有一定的参考价值。
一、深度优先搜索是什么
在一个求解问题答案的过程中,有几种求解的方法。最为暴力的就是枚举法。枚举法枚举每一个答案即会产生一个状态,这些状态就会构成一棵解答树。当然,对于大多数题目而言,这些状态大多是无用的,这也就决定了枚举法的低效。
那么,难道就没有方法进行优化了吗?
答案是有的。因为枚举法产生了太多无用状态,所以我们就应该从解答树中去除这些无用的状态。这种方法被称作剪枝。搜索就是剪枝的一种方法。
既然弄清楚了什么是搜索,那么深度优先搜索又是什么呢?
上文介绍了解答树的概念。我们知道,遍历一棵树有两种方式,一种为层次遍历(通常也被称为广度 / 宽度优先遍历);另一种为递归遍历(通常也被称为深度优先遍历)。于是可以得到,递归遍历解答树的方法被称为深度优先搜索,而层次遍历解答树的方法被称为广度 / 宽度优先搜索。
二、深度优先搜索的应用题型
深度优先搜索的应用非常广泛 (也被称为骗分神器)。大多数暴力枚举的题目都可以用深度优先搜索来优化。另外,还有一些问题需要使用回溯法,这种题型非常适合用深度优先搜索来完成。
三、深度优先搜索伪代码
void dfs(一些必要的参数) { // 深搜英文缩写为 dfs
if (到达递归终点) {
比较是否为最优解
return;
}
进行一些操作
dfs(参数); // 进行下一轮搜索
}
四、例题
这是一道非常简单的深搜应用。代码如下
bool vis[N]; // 访问标记数组
int a[N]; // 排列数组,按顺序储存当前搜索结果
void dfs(int step) {
if (step == n + 1) { // 边界
for (int i = 1; i <= n; i++) {
cout << setw(5) << a[i];
}
cout << endl;
return;
}
for (int i = 1; i <= n; i++) {
if (vis[i] == 0) {
vis[i] = 1;
a[step] = i;
dfs(step + 1);
vis[i] = 0;
}
}
return;
}
// 代码来自 OI-Wiki
参考资料:
- 刘汝佳 《算法竞赛入门经典》
- OI Wiki 深度优先搜索
以上是关于简述深度优先搜索的主要内容,如果未能解决你的问题,请参考以下文章
集册 | Java 实现图的广度优先搜索(BFS)算法,一起深度学习算法思维!