递归调用打印问题
/*
递归能够解决什么样的问题呢
阶乘 8皇后 魔攻问题 最短路径问题
举个例子 球和篮子
如果是两个球放到两个篮子里面
就是3种结果(1 1)(2 0)(0 2)
像快速排序 二分查找 归并排序等算法都需要用到递归
递归需要遵循的重要规则
方法区内存是独立的,不受外部影响
如果递归的是引用数据类型,那么引用指向的数据将会被共享
如果无限递归,则会出现栈溢出异常java,lang.StackOverflowError
所以需要向递归的条件边界趋近
*/
public static void main(String[] args) {
test(6);
}
private static void test(int i) {
if (i > 1){
test(i - 1);
}
System.out.print(i + " "); // 1 2 3 4 5 6
}
/*
打印规则递归调用规则
使用栈模拟递归调用
方法栈帧首先指向main
每调用依次方法
都会在栈帧上方开辟新的空间
一直开辟到test(1)
此时栈帧指向test(1)
然后开始在栈顶调用System.out.print方法
因为每一个方法都会等内部的方法执行结束后再去执行下一行代码
直到main方法上面的栈帧执行完毕
main方法栈帧指向的test方法才算执行完毕
接着就可以执行test方法的下一个方法了
*/
迷宫问题递归实现
/**
* class maze
*
* @author 404 little dinosaur
*/
class Maze{
/*
需求:
小球从初始值[1][1]开始出发
寻找出口[6][5]
找到最短路径
小球走过的路用2表示
并输出每次小球走过的坐标
返回能否到达出口
*/
public static void main(String[] args) {
/*
二维数组模拟迷宫
*/
int[][] maze = new int[8][7];
/*
使用1模拟墙
边界部分围上墙
*/
/*
最上面和最下面围成墙
*/
for (int i = 0; i < 7; i++) {
maze[0][i] = 1;
maze[7][i] = 1;
}
/*
最左边和最右边围成墙
*/
for (int i = 0; i < 6; i++) {
maze[i][0] = 1;
maze[i][6] = 1;
}
/*
中间有一堵墙
*/
maze[3][1] = 1;
maze[3][2] = 1;
/*
输出迷宫情况
*/
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 7; j++) {
System.out.print(maze[i][j] + " ");
}
System.out.println();
}
/*
给小球找通路
*/
boolean lookForExit = lookForExit(maze, 1, 1, 6, 5);
System.out.println(lookForExit); // true
System.out.println();
/*
输出标识后的地图
*/
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 7; j++) {
System.out.print(maze[i][j] + " ");
}
System.out.println();
}
}
/**
* 使用递归回溯来给小球找路
* @param maze 地图
* @param x 小球的横坐标
* @param y 小球的纵坐标
* @param x1 出口横坐标
* @param y1 出口纵坐标
* @return 是否找到出口
*/
private static boolean lookForExit(int[][] maze,int x,int y,int x1,int y1){
/*
实现思路:
探索过的点使用3表示
可以保证回溯的时候不会重复探索
玩迷宫是有策略的
如果出现3个方向
需要一条一条探索
如果走不通
再回到分叉点
走另外一条路
直到走通为止
在程序中
一共有四条路可以探索 下上左右
最终走出来的路线与探索顺序有密切联系
*/
if (maze[x1][y1] == 2){
/*
程序运行到此处
说明找到通路
返回真
*/
return true;
}else{
/*
程序运行到此处
说明递归正在按顺序找通路
此时再次探索会有如下几种情况
0 1 2 3
需要分情况讨论
*/
if (maze[x][y] == 0){
/*
程序运行到此处
说明这条路可以走
maze[x][y] = 2;
这句代码每次递归都会执行到
假设这条路可以走
*/
maze[x][y] = 2;
if (lookForExit(maze,x + 1,y,x1,y1)){ // 向下走
/*
程序运行到此处
说明这条递归可以继续递归
小球继续探索下面这条路
*/
return true;
}else if (lookForExit(maze, x, y + 1, x1, y1)){ // 向右走
return true;
}else if (lookForExit(maze, x - 1, y, x1, y1)){ // 向上走
return true;
}else if (lookForExit(maze, x, y - 1, x1, y1)){ // 向左走
return true;
}else{
/*
程序运行到此处
说明这是一条死路
走不通
标记为3
小球不会走这条路
*/
maze[x][y] = 3;
return false;
}
}else {
/*
程序运行到此处
说明这个点是1 2 3
这个时候运行到此处的
递归退出程序
*/
return false;
}
}
}
/*
另外一种情况
我们在第2行第3列的位置放上挡板
我们在第3行第3列的位置放上挡板
然后运行
发现是2个3
说明整条路通往死胡同
最里面的点到分叉点一路
都会被标记为3
思考:如何求最短路径
把所有的策略用数组表示出来
然后把每个策略得到的节点进行统计
地图中2长度最少的就是最短路径的策略
*/
}
递归解决迷宫问题
本文探讨了如何使用递归调用来解决迷宫问题。首先分析了递归调用在打印问题中的应用,随后详细讲解了迷宫问题的递归实现,提供了具体的算法思路和步骤。最后给出了内容的总目录。
3万+

被折叠的 条评论
为什么被折叠?



