(Basic algorithm学习笔记)《基础算法四》- 深度优先搜索(Depth First Search,DFS )
来源:互联网 发布:python程序员工资 编辑:程序博客网 时间:2024/06/05 04:51
深度优先搜索
深度优先搜索(Depth First Search,DFS )
先引入一个 example
- 现在 我们有 三个盒子 排序 1 , 2 , 3
我们手里也有三个卡牌 1 , 2 , 3
首先我们约定一个规则: 每次到达一个盒子的时候 都是先放1再放2最后放3
#include <stdio.h>#include <stdlib.h>int boxes[10]; // 1-9 个盒子 int books[10]; // 记录 卡牌是否扔进盒子里,就是记录是否使用了 卡牌,使用则为1 没用则为0int n; // 输入的 盒子数 // Depth First Search //step: 第step盒子 void DFS(int step){ int i; //step = n+1 说明 递归 之前的 n步都已经完成即所有的 数都已经扔进盒子里了此时 打印 顺序即可 if(step == n+1) { for(i=1; i<=n; i++) { printf("%d",boxes[i]); } printf("\n"); return ; // 此时 返回到上一次的递归的地方(即最近一次调用DFS函数的位置) } // 遍历 1 - n的数字 // 此时选择数字扔到 step号码盒子里 for(i=1; i<=n; i++) { // i这个数字没有放入 盒子里 if(books[i] == 0) { //往step这个盒子里放入i这个数字 boxes[step] = i; // 相当于flag 此时 这个i数字已经被记录 放入盒子里了 books[i] = 1; // step盒子 放入后开始 实施下一个盒子的操作 DFS(step+1); // 得到 递归回来的时候说明 以下的 递归的可能都 遍历完了之后回来 // 还需要把之前递归 放入的数字 拿出来之后才能继续 放数字 books[i] = 0; } } return ;}int main(int argc, char *argv[]){ scanf("%d",&n); DFS(1);// 从 第一个盒子开始放数字 system("PAUSE"); return 0;}
有详细注释仔细看完大概有以下几个概念:
(1).这也是一种遍历,但是是一种递归的方式更加 巧妙
(2).因为用的是递归所以每一步的操作相同(也是算法核心基础)
(3).有标志位来记录 是否用过数字并且在 递归之后有个 books[i]=0的操作
2 、 现在可以 基础写出深度优先搜索的伪代码
void DSF(int step){ 判断边界(一个结束的条件之后return) 尝试每一种可能(一般是for循环) { 这一步结束后 继续下一步的操作(递归)DSF(step+1); } return(返回)}
3、 之后的 一个例子就是按这个 方式来写
回忆一下前一个博客写的枚举算法中的 那个 问题三位数+三位数= 三位数
这回我们采用这种方法来写
分析:
(1):首先来看条件:结束条件 为 满足 三位数+三位数=三位数 这个等式即可 之后输出这个组合
(2): 尝试每一个可能,咱们可以类比一下,将数字分成1-9个数字
而三位数的百位,十位,个位为 相应的箱子,其实还是往箱子里面 扔数字,之后 满足(1)的条件 返回 即可开始尝试下一个组合
见代码(在上面的代码上稍作修改):
#include <stdio.h>#include <stdlib.h>int boxes[10]; // 1-9 个盒子 int books[10]; // 记录 卡牌是否扔进盒子里,就是记录是否使用了 卡牌,使用则为1 没用则为0int total;// 组合的个数 // Depth First Search //step: 第step盒子 void DFS(int step){ int i; //step = n+1 说明 递归 之前的 n步都已经完成即所有的 数都已经扔进盒子里了此时 打印 顺序即可 if(step == 10)//n修改 { // 条件修改 if(boxes[1]*100+boxes[2]*10+boxes[3]+boxes[4]*100+boxes[5]*10+boxes[6] == boxes[7]*100+boxes[8]*10+boxes[9]) { total ++; printf("%d%d%d+%d%d%d=%d%d%d\n",boxes[1],boxes[2],boxes[3],boxes[4],boxes[5],boxes[6],boxes[7],boxes[8],+boxes[9]); } return ; // 此时 返回到上一次的递归的地方(即最近一次调用DFS函数的位置) } // 遍历 1 - n的数字 // 此时选择数字扔到 step号码盒子里 for(i=1; i<=9; i++)// n修改 { // i这个数字没有放入 盒子里 if(books[i] == 0) { //往step这个盒子里放入i这个数字 boxes[step] = i; // 相当于flag 此时 这个i数字已经被记录 放入盒子里了 books[i] = 1; // step盒子 放入后开始 实施下一个盒子的操作 DFS(step+1); // 得到 递归回来的时候说明 以下的 递归的可能都 遍历完了之后回来 // 还需要把之前递归 放入的数字 拿出来之后才能继续 放数字 books[i] = 0; } } return ;}int main(int argc, char *argv[]){ DFS(1);// 从 第一个盒子开始放数字 printf("total=%d",total/2); system("PAUSE"); return 0;}
3、 再来个例子,再来试着和我一起分析一下
现在有一个迷宫 0代表 可以走的地方 1代表 障碍物
一个 人加入在 (3,4)这个位置,我们从(1,1)走 怎么去 最快的找到他 ,顾名思义,可能是 最短距离去搜索对吧? 此处我们来用 深度优先搜索
(1) 首先制定一个规则,每次 我们都 先尝试向右, 向下,向左,向上的顺序 来 走
(2) 最后的条件为 达到 那个 人的 位置则为 条件满足(其实就是x和y坐标满足,之后 来找出最小的 path则 需要 进行比较赋值处理看一眼代码你就懂了 )
(3) 遍历还是 遍历 右下左上,去遍历这里我们可以 来定义一个数组来表示 这四个操作
(4) 遍历的过程中 有条件限制:
a. 越界 越界的话直接 尝试 下一个 操作即 通过continue来 实现
b. 是否是 障碍物 需要判断 障碍物不能行走
c. 这里很容易 忘掉的 一点,那就是 你以前走过的路 应该不需要 再走回去吧???所以 这里也需要if条件判断
那么好 现在已经全部分析完成开始准备代码
代码如下:
#include <stdio.h>#include <stdlib.h>int aimX,aimY;// 目标x,y int minStep = 99999999 ; // 最短距离 int n,m; // n为行,m为列 int boxes[51][51]; // 迷宫 int books[51][51]; // 走过的 标志 void DFS(int x, int y, int step){ //向右,向下,向左,向上 int next[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; int tx,ty,i; // 满足的条件 抵达目标处 if((x==aimX)&&(y==aimY)) { // 要最小的 路程步数 if(minStep>step) { minStep = step; } return ; } // 遍历 四个 走向 for(i=0; i<=3; i++) { // 更新 x,y坐标 tx = x + next[i][0]; ty = y + next[i][1]; //判断是否越界 越界 则 调到下一个走向 if(tx<1 || tx>n || ty<1 || ty>m) { continue; } //1. 判断是否 为平地即无障碍物 //2. 判断这一点是否走过 if((boxes[tx][ty] == 0)&&(books[tx][ty]==0)) { books[tx][ty] = 1;// 标志这个点走过了 DFS(tx,ty,step+1);// 下一个点的操作 books[tx][ty] = 0;// 遍历结束将走过的点的标志去掉 } } return;}int main(int argc, char *argv[]){ int i,j; int startx,starty;//开始的 x,y坐标 scanf("%d %d",&n,&m); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&boxes[i][j]); } } scanf("%d %d %d %d",&startx,&starty,&aimX,&aimY); books[startx][starty] = 1;//先记录 起始点 走过了 要不会多一次遍历。 DFS(startx,starty,0); printf("%d",minStep); system("PAUSE"); return 0;}
输入
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
显示
7请按任意键继续…
- (Basic algorithm学习笔记)《基础算法四》- 深度优先搜索(Depth First Search,DFS )
- [数据结构]深度优先搜索算法(Depth-First-Search,DFS)
- 图的深度优先搜索(Depth First Search,DFS)
- 5.3.2 深度优先搜索(Depth-First-Search,DFS)
- DFS-深度优先搜索(Depth First Search)—1
- TensorFlow中的深度优先搜索(Depth-first search, DFS)
- DFS——深度优先算法(Depth First Search)
- 深度优先搜索算法(DFS,Depth First Search)的PHP实现
- DFS --- Depth First Search 深度优先搜索算法
- 深度优先搜索(Depth-First-Search,DFS)
- 深度优先搜索算法(Depth first search)
- 深度优先搜索算法(Depth-First-Search)
- 深度优先搜索(Depth-First-Search)
- 穷竭搜索之深度优先搜索DFS(Depth-First Search)
- 图的遍历之深度优先搜索(Depth-First Search—DFS)
- 深度优先搜索Depth-first search (DFS) for undirected graphs
- 深度优先搜索DFS(depth first search),拓扑排序
- 【算法总结系列-6】深度优先搜索-Depth First Search,DFS
- HTML基础学习四
- swagger注解 详细说明
- hdu 1027 Ignatius and the Princess II (dfs+剪枝)?
- SpringBoot之开启Profile
- python里怎么实现多个协程一起执行,只要完成一个就返回一个协程
- (Basic algorithm学习笔记)《基础算法四》- 深度优先搜索(Depth First Search,DFS )
- ES6变量的解构赋值
- 最小费用最大流--uva1658 Admiral
- 禁用,绕过代理
- linux下使用 du查看某个文件或目录占用磁盘空间的大小
- solr包结构介绍,solrCore的安装配置,solr部署到Tomcat,多solrCore配置,配置中文分词器,界面功能介绍,Schema.xml的基本使用,数据导入
- 查看已安装Tomcat的版本号
- Tomcat目录结构
- Java 多态