ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

简述深度优先搜索

2021-06-06 02:03:42  阅读:258  来源: 互联网

标签:优先 遍历 枚举法 dfs 简述 搜索 深度


一、深度优先搜索是什么

在一个求解问题答案的过程中,有几种求解的方法。最为暴力的就是枚举法。枚举法枚举每一个答案即会产生一个状态,这些状态就会构成一棵解答树。当然,对于大多数题目而言,这些状态大多是无用的,这也就决定了枚举法的低效。

那么,难道就没有方法进行优化了吗?

答案是有的。因为枚举法产生了太多无用状态,所以我们就应该从解答树中去除这些无用的状态。这种方法被称作剪枝。搜索就是剪枝的一种方法。

既然弄清楚了什么是搜索,那么深度优先搜索又是什么呢?

上文介绍了解答树的概念。我们知道,遍历一棵树有两种方式,一种为层次遍历(通常也被称为广度 / 宽度优先遍历);另一种为递归遍历(通常也被称为深度优先遍历)。于是可以得到,递归遍历解答树的方法被称为深度优先搜索,而层次遍历解答树的方法被称为广度 / 宽度优先搜索。

二、深度优先搜索的应用题型

深度优先搜索的应用非常广泛 (也被称为骗分神器)。大多数暴力枚举的题目都可以用深度优先搜索来优化。另外,还有一些问题需要使用回溯法,这种题型非常适合用深度优先搜索来完成。

三、深度优先搜索伪代码

void dfs(一些必要的参数) {    // 深搜英文缩写为 dfs
    if (到达递归终点) {
        比较是否为最优解
        return;
    }
    进行一些操作
    dfs(参数); // 进行下一轮搜索
}

四、例题

洛谷 P1706 全排列问题

这是一道非常简单的深搜应用。代码如下

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

参考资料:

标签:优先,遍历,枚举法,dfs,简述,搜索,深度
来源: https://www.cnblogs.com/Cristime/p/14854409.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有