Java 初识递归
Java 递归
- 什么是递归
- 递归: 即在成员方法内调用自身
- 递归的优点
- 能用简洁的代码解决复杂的问题
- 递归的缺点
- 对内存的消耗大
- 递归的应用场景
- 当我们要获取一个结果,但是这个结果依赖与上一步一样操作所得到的结果,才能进行运算时,可以使用递归
- 回溯:有多个选择,但不确定哪个是正确的可以使用递归的回溯现象进行逐一尝试
递归的使用
即在成员方法内调用自身方法
public class ...... {
// 实例化对象
Recursion func = new Recursion();
// 调用 function 方法
func.function(10);
}
class Recursion {
public void function (int number) {
if (number == 1) {
return;
}
System.out.println(number);
}
}
递归的注意事项
- 因为
JVM
会为每个调用的方法单独开辟一个临时栈,每调用一次开辟一个,只要方法不结束,这个栈就会一直存在,所以递归的层次不能太多次。 - 递归一定要有出口,即:退出条件
- 递归必须拥有最少一个形参
递归的经典应用
阶乘
public class ...... {
// 实例化对象
Recursion object = new Recursion();
// 调用 阶层 方法
object.factorial(10);
}
class Recursion {
/**
* @param number 阶乘层数
* @return 阶层结果
*/
public int factorial (int number) {
if (number == 1) {
// 当 number = 1 时退出递归
return 1;
}
// 利用上一层的结果 来计算
// factor...(number - 1) * 2
// factor...(number - 1) * 3
// factor...(number - 1) * 4......
return factorial(number - 1) * number;
}
}
递归的回溯现象
回溯也是递归的常用方法,如:
- 当前有n个方案,方案1、方案2、方案3......,我们不确定哪个方案是能解决问题
- 先尝试方案1 方案1能通过执行后续代码
- 如不同通过尝试方案2以此类推
如寻路案例
public class ...... {
public static void main (String[] args) {
Map mapObject = new Map();
int map[][] = mapObject.genMap(8, 7);
System.out.println("寻路结果如下:\n" + mapObject.findWay(map, 1, 1));
// 打印寻路结果
new Arrayss().printArrays(map);
}
}
class Map {
// 用于记录出口位置
int exportX;
int exportY;
/**
* 生成地图
* @param row 行
* @param column 列
* 0 表示可走
* 1 表示障碍物
*/
public int[][] genMap (int row, int column) {
int map[][] = new int[row][column];
// 生成一个四边围的地图
for (int rows = 0; rows < row; rows++) {
for (int columns = 0; columns < column; columns++) {
if (rows == 0 || rows == row - 1 || columns == 0 || columns == column - 1) {
map[rows][columns] = 1;
}
}
}
// 随机生成1~10个障碍物
for (int randomCount = 1; randomCount <= (int)(Math.random() * 10) + 1; randomCount++) {
// 随机指定可活动行
int randomRow = (int)(Math.random() * (row - 2)) + 1;
// 随机指定可活动列
int randomColumn = (int)(Math.random() * (column - 2)) + 1;
// 随机位置生成障碍物
map[randomRow][randomColumn] = 1;
}
// 记录随机出口位置
exportX = (int)(Math.random() * (column - 2)) + 1;
exportY = (int)(Math.random() * (row - 2)) + 1;
map[exportY][exportX] = 2;
// 打印地图未寻路前
new Arrayss().printArrays(map);
map[exportY][exportX] = 0;
return map;
}
/**
* @param map 地图
* @param x 当前位置x坐标
* @param y 当前位置y坐标
* @return boolean 此位置是否可通
*/
public boolean findWay (int map[][], int x, int y) {
switch (map[exportY][exportX]) {
// 如果 出口位置等于2
// 说明程序已经走到出口位置,返回true
case 2:
return true;
// 处理当前位置不为出口位置的情况
default:
switch (map[y][x]) {
// 当前位置为 0 说明可进行尝试
case 0:
// 假定当前位置可从上下左右其中一个走同
map[y][x] = 2;
// 尝试向下寻路
if (findWay(map, x, y+1)) {
return true;
}
// 尝试向右寻路
else if (findWay(map, x+1, y)) {
return true;
}
// 尝试向左寻路
else if (findWay(map, x-1, y)) {
return true;
}
// 尝试向上寻路
else if (findWay(map, x, y-1)) {
return true;
}
// 如果四个方向都不通
else {
// 将当前位置记录为 3 并返回false
map[y][x] = 3;
return false;
}
default:
// 当前位置不为 0 说明是死路返回false并退出
return false;
}
}
}
}
class Arrayss {
public void printArrays (int array[][]) {
for (int twoDimensional = 0; twoDimensional < array.length; twoDimensional++) {
for (int index = 0; index < array[twoDimensional].length; index++) {
System.out.print(array[twoDimensional][index] + " ");
}
System.out.println();
}
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析