java递归(迷宫问题)

前言

学会了递归的实现原理后,我们就可以使用递归来解决一些简单的实际问题,本文讲解的是迷宫问题。

一、问题描述

给出一个大小为n*n的二维数组map,该数组表示的是一幅地图,1表示障碍物,0表示通路,给出起始坐标(s1,y1)和终点坐标(s2,y2),要求输出图中起始位置到终点位置的路径。

二、思路分析

这是一个经典的递归问题,首先我们从起始坐标开始,选择一个方向进行递归查找,如果找到终点坐标就递归结束找到路径,如果碰到障碍物就返回上一级进行回溯换另一个方向查找,最后回溯完了还没找到就递归结束没找到路径。

三、过程图解

在这里插入图片描述
图中对递归过程进行了非常详细的描述,也体现了回溯过程的所有细节,相信不懂递归的小伙伴看懂该图后一定能对递归有深刻的认识。

四、测试源码

package com.yc.recursion;

public class MiGong {

	public static void main(String[] args) {
		int [][] map = new int[][]{
			{1,1,1,1,1,1,1},
			{1,0,0,0,0,0,1},
			{1,0,0,0,0,0,1},
			{1,1,1,0,0,0,1},
			{1,0,0,0,0,0,1},
			{1,0,0,0,0,0,1},
			{1,0,0,0,0,0,1},
			{1,1,1,1,1,1,1}
		};
		for(int i=0;i<8;i++){
			for(int y=0;y<7;y++){
				System.out.print(map[i][y]+" ");
			}
			System.out.println();
		}
		System.out.println();
		setWay(map,1,1);
		for(int i=0;i<8;i++){
			for(int y=0;y<7;y++){
				System.out.print(map[i][y]+" ");
			}
			System.out.println();
		}
	}
	/**
	 * 查找路径 2表示路径上的一点,3表示查找过的一点
	 * @param map
	 * @param i
	 * @param j
	 * @return
	 */
	private static boolean setWay(int[][] map, int i, int j) {
		if(i==6&&j==5){
			return true;
		}else{
			if(map[i][j]==0){
				map[i][j] = 2;
				//递归判断是否能找到
				//回溯查找其它方向
				if(setWay(map,i+1,j)){		//向下查找
					return true;
				}else if(setWay(map,i,j+1)){//向右查找
					return true;
				}else if(setWay(map,i,j-1)){//向上查找
					return true;
				}else if(setWay(map,i-1,j)){//向左查找
					return true;
				}else{
					map[i][j] = 3;
					return false;
				}
			}else{
				return false;
			}
		}
	}
}


总结

这是递归的第一个实际应用,弄懂了这个问题但不一定能弄懂其他的递归问题,希望我们能保持一颗虔诚的心,不断的学习,用学过的知识去解决更多的问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我无法绘制流程图,但是我可以为您解答迷宫问题递归算法。 对于迷宫问题递归求解,一般需要用到回溯法。简单来说,我们可以从起点开始,按照一定的规则(如按照顺序尝试上下左右四个方向,或者按照某种优先级顺序尝试)尝试向前走。如果遇到障碍物或者到达边界,则需要回溯到上一个选择点,然后尝试其他未尝试过的方向。这样不断地选择和回溯,直到找到终点或者所有路径都尝试过为止。下面是比较常见的代码实现: ```java public static boolean mazeSearch(int[][] maze, int i, int j, int[][] mark) { // 输入迷宫地图、当前位置、标记数组 // 若当前位置是终点,则返回 true if (i == maze.length - 1 && j == maze[0].length - 1) { return true; } // 若当前位置没有走过且不是障碍物,则继续走 if (i >= 0 && i < maze.length && j >= 0 && j < maze[0].length && maze[i][j] == 0 && mark[i][j] == 0) { mark[i][j] = 1; // 标记为已经走过 // 尝试上下左右四个方向 if (mazeSearch(maze, i-1, j, mark) || mazeSearch(maze, i+1, j, mark) || mazeSearch(maze, i, j-1, mark) || mazeSearch(maze, i, j+1, mark)) { return true; // 若有一条路径成功,则返回 true } mark[i][j] = 0; // 否则回溯到上一个选择点 } return false; // 若所有路径都失败,则返回 false } ``` 上面的算法会尝试从起点(0,0)开始走,依次向上、下、左、右四个方向尝试,如果遇到障碍物或者到达边界则回溯到上一个选择点。为了避免重复走某个点,我们需要一个标记数组mark,用于标记哪些点已经走过,哪些点是障碍物。最后,若递归到终点,则返回true,否则返回false。 希望这个回答能够解决您的问题。如果您还有其他问题或者需要进一步的帮助,请随时联系我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值