深度优先遍历及例题加讲解

竞赛里面重要算法,全当学习笔记啦。(如有不足多多谅解)

零、什么是深度优先遍历

深度优先遍历简称DFS(Depth First Search)。
我们简单的举个栗子:
从前有位首富打野,一共14个打野点,首富从1号打野点开始,要打遍所有野区,可以有什么样的打野路线呢?

我们假设挑一个方向打野打到底,我们选择一条支路,尽可能不断深入,如果遇到死路就往回退,回退过程中如果遇到没打过的野怪就进入这条支路继续深入打野。

在图中,我们先从1号点,到2号一直道6号(蛤蟆)。这个时候发现已经是个死胡同了,不能再往前走了(男枪:懂事的打野已经去上路假装gank,再吃波兵线)

于是,我们退回到五号打野点,然后往8号点走,然后又无路可走了,于是退回到2号点,沿着2号点方向打野即探索2-12-13-14

按照这个思路,我们探索完2号点方向,就退回到1号点向其他没有打过野的方向探索。
像这样先深入探索,走到头再退回寻找其他出路的遍历方式,就叫做深度优先搜索。

二、深度优先遍历例题

(一)对数字全排列相关问题

1.题目:
对数字1-9进行全排列,求出1-9全排列有多少种。

2.基础深度优先遍历例题。

3.解题代码:

//用dfs解决1-9的全排列个数问题 #include<bits/stdc++.h>
using namespace std;
int total=0;//用于计数
int check[10]={0};//检查当前数字有没有用过,用过了就标记为1,也可以用bool类型
int lista[10]={0};//用于存储排列结果
void dfs(int step){if(step==10){total++;/*  显示排列结果 for(int j=1;j<=9;j++){cout<<lista[j];} */return;}for(int i=1;i<=9;i++){ //1-9个数字循环 if(check[i]==0){check[i]=1;  //当前i这个数字用过,标记为1; lista[step]=i;//存储结果 dfs(step+1);//进行下一个位置的数字选择 check[i]=0;//将用过的数字再标记为0,再使用; }}
}
int main(){dfs(1);cout<<total;
}

同样的也可以用c++的一个函数直接求解,如下:


```cpp
//用next_permutation函数进行全排列(升序)
//需要头文件#include<algorithm> #include<bits/stdc++.h>
using namespace std;
int main(){int a[10]={1,2,3,4,5,6,7,8,9};int cnt=0;do{cnt++;}while(next_permutation(a,a+9));cout<<cnt;
}

4.稍微进阶一点的题目:
1-9数字对应着a-9个字母,使得ab+cd+ef+gh+i=141,问有多少种可能?
这题仅仅在原有基础上,添加一些限制条件。
代码:

#include<bits/stdc++.h>
using namespace std;
int total=0;//用于计数
int check[10]={0};//检查当前数字有没有用过,用过了就标记为1,也可以用bool类型
int lista[10]={0};//用于存储排列结果
int cnt=0;bool checka(){//使用布尔类型进行结果检测 int t=lista[1]*lista[2]+lista[3]*lista[4]+lista[5]*lista[6]+lista[7]*lista[8]+lista[9];if(t==141){return true;}return false;
}void dfs(int step){int t=0;if(step==10){//total++;/*  显示排列结果 for(int j=1;j<=9;j++){cout<<lista[j];} */if(checka()){//调用布尔类型,得出符合结果加一。 cnt++;} return;}for(int i=1;i<=9;i++){ //1-9个数字循环 if(check[i]==0){check[i]=1;  //当前i这个数字用过,标记为1; lista[step]=i;//存储结果 dfs(step+1);//进行下一个位置的数字选择 check[i]=0;//将用过的数字再标记为0,再使用; }}
}
int main(){dfs(1);cout<<cnt;
}

(二)对地图路径种类问题
1.题目:
如下地图,0的位置可以走,1的位置是路障不能走,问从左上角到右下角有多少种走法?

 0,0,0,1,0,0,1,0,0,0,0,0,0,1,1,0,1,0,0,0.

2.深度优先遍历简单例题,从左上角开始,先深入走一遍,不通或者到达了就返回再走另一个方向。
3.解题代码:

 #include<bits/stdc++.h>
using namespace std;
int check[5][6]={0};//检查当前地点有没有走过,走过为1;
int mape[5][6]={0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,};
int x[4]={0,1,0,-1};//决定走的方向
int y[4]={1,0,-1,0};
int total=0;
void dfs(int xx,int yy){check[1][1]=1;int tx=1,ty=1;if(xx==4&&yy==5){//到达目的地,计数加一total++;return ;}for(int i=0;i<4;i++){tx=xx+x[i];ty=yy+y[i];if(tx<1||tx>5||ty<1||ty>6)continue;//不能超过边界if(check[tx][ty]==0&&mape[tx][ty]==0){check[tx][ty]=1;dfs(tx,ty);check[tx][ty]=0;}}
}
int main(){dfs(1,1);cout<<total;
}

4.八皇后问题:
有六位皇后,在一个6x6的表格中,有六个皇后,为了让他们不互相攻击(不在同一行同一列同一斜方向),请给她们安排位置。
如下图:

经典八皇后问题,关键点在于限制条件:不在一个列,不在一个斜线,
不在一个列用checklie[j]=0;然而不在一个斜线则发现行号x与列号j之间的关系:
x+j与x-j+6是固定值即:checkxie[x+j]=0;checkxie2[x-j+6]=0;
解题代码:

#include<bits/stdc++.h>
using namespace std;
int checklie[100]={0};//判断当前列有没有用过
int checkxie[100]={0};//判断右上和左下的那条斜线有没有用过
int checkxie2[100]={0};//判断左上和右下的那条斜线有没有用过
int total=0;//记录结果数
void dfs(int x){ //x当前行数 if(x==7){//当前x=7是结束,结果加一 total++;return;} for(int i=1;i<=6;i++){if(checklie[i]==0&&checkxie[x+i]==0&&checkxie2[x-i+6]==0){//判断 checklie[i]=1;checkxie[x+i]=1;checkxie2[x-i+6]=1;dfs(x+1);//继续深搜下一行 checklie[i]=0;//回溯 checkxie[x+i]=0;checkxie2[x-i+6]=0;}}
}
int main(){dfs(1);cout<<total;
}

关于深度优先遍历算法-c++语言相关推荐

  1. Python算法系列—深度优先遍历算法【二叉树】

    深度优先遍历算法之二叉树 一.什么是深度优先遍历 二.二叉树 1. 二叉树简介 2.二叉树类型 3.二叉树相关术语 4. 二叉树的节点代码 5. 二叉树遍历顺序 6.深度优先遍历和广度优先遍历 三.面 ...

  2. 实验报告C语言实现图的深度遍历,图的深度优先遍历的C语言实现.pdf

    图的深度优先遍历的C语言实现.pdf 维普资讯 九 江 职 业 技 术 学 院 学 报 JournalofJiujiangVocational&TechnicalCollege 2004.2 ...

  3. 深度优先遍历算法-01小偷偷东西问题

    小偷偷东西问题 前言 深度优先遍历是经典的图论算法,深度优先遍历算法的搜索逻辑和它的名字一样,只要有可能,就尽量深入搜索,直到找到答案,或者尝试了所有可能后确定没有解. 简单来说,深度优先遍历就是按照 ...

  4. 带父节点的平衡二叉树_Python算法系列—深度优先遍历算法【二叉树】

    一.什么是深度优先遍历 深度优先遍历算法是经典的图论算法.从某个节点v出发开始进行搜索.不断搜索直到该节点所有的边都被遍历完,当节点v所有的边都被遍历完以后,深度优先遍历算法则需要回溯到v以前驱节点来 ...

  5. c语言遍历算法的头文件,图优先遍历算法(C语言版).doc

    图优先遍历算法(C语言版) 众炼向饭桨泞奉源柿虐萧宰徽强药邻摘甭膜酣猖椅支习洋瞪较效笋盏厚婪跳博险僳乘措笆却问谬闸皇机兽偿谐芹违邹竞芬襟竣备烘令救汇邵叙鹰扭肾钙苏辅捕先是埠郧苛三驯溅烂右井准刮修柒拿苇 ...

  6. 图的遍历(搜索)算法 之 深度优先遍历算法

    图的遍历的定义: 从图中的某个顶点出发访问遍图中的所有顶点,并且每个顶点仅仅被访问一次. 图的遍历算法我们常见的而且用的最多的就有两种:其一是图的深度优先遍历算法:其二是图的广度优先遍历算法.这里我们 ...

  7. rapidio 网络枚举--深度优先遍历算法

    根据 RapidIO 协议规范在 RapidIO 路由网络拓扑结构中,一般采用深度优先遍历 的枚举算法,因为广度优先遍历算法空间复杂度大,在规模较大的 RapidIO 网络中容易找 不到最优路径. R ...

  8. 二叉树非递归后序遍历算法(C语言)

    二叉树非递归后序遍历算法(C语言) 二叉树后序遍历的规律:左右根 后序非递归遍历中,访问根(子根)结点有两种情况 ①:遍历完左子树,需要遍历右子树,需要从栈中访问最顶上的根(子根)结点从而得到右子树的 ...

  9. 深度优先遍历算法-03二叉树路径遍历问题

    二叉树路径遍历 简述 比较基础的一个DFS的题目,但是确实很多难题的模板.LeetCode很多二叉树的题本质上就是这个路径遍历. 本题为了输出路径,使用DFS的经典结构栈完成. 问题描述 给定一个二叉 ...

最新文章

  1. python怎么画函数图_可视化|Python绘制桑基图
  2. Java 虚拟机总结给面试的你(中)
  3. 【Android游戏开发十四】深入Animation,在SurfaceView中照样使用Android—Tween Animation!...
  4. spring-DAO
  5. saltstack的简单安装和配置
  6. Spring.NET学习笔记13——AOP的概念(基础篇) Level 200
  7. mybatis多表查询出来的实体如何映射_mybatis进阶案例之多表查询
  8. OO第二次课程总结分析
  9. android的环境搭建与配置
  10. Adobe Flash cs4 下载安装
  11. ImportError: cannot import name 'imsave' from 'scipy.misc' (C:\Users\DELL\AppData\Roaming\Python\Pyt
  12. BVH with SAH (Bounding Volume Hierarchy with Surface Area Heuristic)
  13. makefile编译子目录
  14. 第13课:实战之用 Python 写一个抢票软件
  15. Vue源码流程图(函数名与源码对应)
  16. 【复杂网络建模】——通过图神经网络来建模分析复杂网络
  17. 机器学习算法-线性回归
  18. 完美玩机 三星I9000解锁工具实测教程
  19. Pandas操作dataframe对所有列/行求和 ,对指定列/行求和,对某一列/行求和,并添加新的列/行
  20. tomcat 启动报端口被占用(windows)

热门文章

  1. codeforse比赛:Noobs Round #2 (Div. 4) by Rudro25
  2. 基于单片机的电梯(四层)控制系统设计
  3. unity5.3 VR开发
  4. 英雄联盟游戏环境异常
  5. 【邢不行|量化小讲堂系列49-实战篇】量化投资中,计算技术指标时常见的8个坑
  6. 如何构建事件驱动的量化策略【邢不行|量化小讲堂系列61-实战篇】
  7. applecare多少钱?_AppleCare +值得吗?
  8. 如何把微课应用到计算机课堂,浅谈微课在信息技术课堂中的应用
  9. 一位项目管理专家总结的项目职场技巧
  10. java 08_java08