DFS算法总结

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
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值