DFS算法总结
dfs是不断沿顶点的深度方向遍历的方法,必须有递归思想做支撑。
代码框架
全局上还要考虑的参数有:
数组Map(表示dfs搜索的整体范围)、数组vis(表示范围内每个位置状态flag)等。
public void dfs(主体参数){
if(参数到达边界&&满足终止条件){
执行终止事件
return;
}
if(判断当前状态合理&&未被标记){
标记当前状态位置;
dfs(下一位置);
还原当前位置标记;
}
}
应用一:全排列问题
例:给定ABC三个字母,输出全排列
思路:从1~3依次判断字母位置
static char[] letter = {'A','B','C'};
static char[] Map = new char[5];
static int[] vis = new int[5];
public static void dfs(int cur){
//退出条件:3个字母都放入Map
if(cur == (3)){
for(int i=0;i<3;i++){
System.out.print(Map[i]+" ");
}
System.out.println();
return;
}
for (int i=0;i<3;i++){
if(vis[i]==0){ //未被访问过
Map[cur] = letter[i];
vis[i] = 1; //标记为访问过
dfs(cur+1);
vis[i] = 0;
}
}
}
public static void main(String[] args) {
dfs(0);
}
结果:
A B C
A C B
B A C
B C A
C A B
C B A
应用二:迷宫问题
迷宫:搜索范围为nxm的迷宫(二维矩阵 1<=n,m<=10)
‘S’:当前位置
‘.’:可以通过
‘*’:障碍物,无法通过
‘T’:迷宫出口
每次可以移动一步:上,下,左,右
static char[][] Map = new char[20][20];
static int[][] vis = new int[20][20];
static int n, m, p, q ,flag=0; //p、q为当前位置
static int[][] dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; //{x轴,y轴}:右,左,上,下
public static void dfs(int x,int y){
//终止条件
if(Map[x][y] == 'T'){
flag = 1;
return;
}
for(int i=0;i<=3;i++){//四个方向
int tx = x+dir[i][0];
int ty = y+dir[i][1];
//判断当前状态是否合理
if(tx>=1&&tx<=n && ty>=1&&ty<=m && Map[tx][ty]!='*' && vis[tx][ty]==0){
vis[tx][ty] = 1;
dfs(tx,ty);
vis[tx][ty] = 0; //方便下一次使用
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] nm = sc.nextLine().split(" ");
n = Integer.parseInt(nm[0]);
m = Integer.parseInt(nm[1]);
flag = 0;
//输入地图
for(int i=1;i<=n;++i){
char[] l = sc.nextLine().toCharArray();
for(int j=1;j<=m;++j){
Map[i][j] = l[j-1];
//初始位置
if(Map[i][j] == 'S'){
p = i;
q = j;
}
}
}
dfs(p,q);//从根节点开始
if(flag == 0){
System.out.println("N");
}else {
System.out.println("Y");
}
}
输入:第一行n m(空格分隔),第二行开始输入迷宫
3 4
S**.
..*.
***T
输出:可以走出迷宫:“Y”否则为“N”
N
输入:
3 4
S**.
....
***T
输出:
Y