方法递归调用

递归能解决什么问题
  1. 各种数学问题:8皇后问题、汉诺塔、阶乘问题、迷宫问题,球和篮子的问题…
  2. 各种算法问题:快排、归并排序、二分查找、分治算法…
  3. 用栈解决的问题(递归代码比较简洁)

递归调用机制
  • 打印问题

    public void test(int n){if(n > 2){test(n-1);}System.out.println("n = " + n);
    }
    

    输入时,n=4,输出什么?

    n = 2
    n = 3
    n = 4
    

  • 阶乘问题

    public int factorial(int n){if(n == 1){return 1;}else{return factorial(n - 1) * n;}
    }
    

    输入时,n=5,输出什么?

120


递归调用重要原则
  1. 执行一个方法时,就创建一个新的受保护的独立栈空间
  2. 方法的局部变量是独立的,不会相互影响,比如n变量
  3. 如果方法中使用的是引用类型变量,比如数组,就会共享该引用类型的数据
  4. 递归必须向退出递归的条件逼近,否则就是无线递归,出现StackOverflowError
  5. 当一个方法执行完毕时,或者遇到return,就会返回,遵守谁调用返回给谁的原则,同时当方法执行完毕或者返回时,该方法也就执行完毕

练习
  1. 请使用递归的方式求出斐波那契数列1,1,2,3,5,8,13…给你一个n,求出第n个值是多少
  2. 猴子吃桃子的问题:有一堆桃子,猴子第一天吃掉了其中的一半,并且多吃了一个。以后没天猴子都吃其中的一半,然后再多吃一个。当到第10天的时候,猴子还没吃,发现只剩下一个桃子了。问:原来一共有多少桃子?
public class RecursionExercise01{public static void main(String[] args) {int n = 7;T t = new T();int value = t.fibonacci(n);System.out.println("第" + n + "个数是" + value);//13int day = 1;int peach = t.peach(day);if (day >= 1) {System.out.println("第" + day + "天,有" + peach + "个桃子");//1534}else{System.out.println("不符合规范");}}
}class T{/*请使用递归的方式求出斐波那契数列1,1,2,3,5,8,13…给你一个n,求出第n个值是多少*///第1个 1//第2个 1//第3个 f(1) + f(2)public int fibonacci(int n){if (n == 1 || n == 2) {return 1;}else{return fibonacci(n - 1) + fibonacci(n - 2);}}/*猴子吃桃子的问题:有一堆桃子,猴子第一天吃掉了其中的一半,并且多吃了一个。以后没天猴子都吃其中的一半,然后再多吃一个。当到第10天的时候,猴子还没吃,发现只剩下一个桃子了。问:原来一共有多少桃子?*///原有的桃子数x,现有的桃子数y// x / 2 - 1 = y, x = (y + 1) * 2//第10天 1//第9天 (day10 + 1)*2//第8天 (day9 + 1)*2public int peach(int day){if (day == 10) {return 1;}else if (day >= 1 && day < 10){return (peach(day + 1) + 1) * 2;}else{return -1;}}
}

迷宫问题
  1. 创建迷宫

    public class Maze{public static void main(String[] args) {//创建8行7列的地图int row = 8, col = 7;int[][] map = new int[row][col];//设置屏障for (int i = 0; i < map[0].length; i++) {//遍历列map[0][i] = 1;//第一行全为1map[row - 1][i] = 1;//最后一行全为1}for (int i = 0; i < map.length; i++) {//遍历行map[i][0] = 1;//第一列全为1map[i][col - 1] = 1;//最后一列全为1}map[3][1] = 1;map[3][2] = 1;//遍历地图for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[i].length; j++) {System.out.print(map[i][j]);}System.out.println();}}
    }
1111111
1000001
1000001
1110001
1000001
1000001
1000001
1111111
  1. 编写递归方法

    class T{//int[][] map, 传入地图。数组是引用类型,所以形参影响实参//int i, int j, 传入当前位置//递归终点是 map[row - 2][col - 2]//0 未走的路,1 障碍,2 可走的路,3 死路别走//策略 下右上左public boolean findWay(int[][] map, int i, int j){int row = map.length;int col = map[0].length;if (map[row - 2][col - 2] == 2) {return true;}else{if (map[i][j] == 0) {map[i][j] = 2;if (findWay(map, i + 1, j)) {//下return true;}else if(findWay(map, i, j + 1)){//右return true;}else if(findWay(map, i - 1, j)){//上return true;}else if(findWay(map, i, j - 1)){//左return true;}else{//上下左右都没路走,认定为死路map[i][j] = 3;return false;}}else{//1,2,3 1和3不能走,2:不能走回头路return false;}}}
    }
    
  2. 测试

T t = new T();
t.findWay(map, 1, 1);//初始位置为1,1//遍历地图
for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[i].length; j++) {System.out.print(map[i][j]);}System.out.println();}
1111111
1200001
1222001
1112001
1002001
1002001
1002221
1111111

完整代码为

public class Maze{public static void main(String[] args) {//创建8行7列的地图int row = 8, col = 7;int[][] map = new int[row][col];//设置屏障for (int i = 0; i < map[0].length; i++) {//遍历列map[0][i] = 1;//第一行全为1map[row - 1][i] = 1;//最后一行全为1}for (int i = 0; i < map.length; i++) {//遍历行map[i][0] = 1;//第一列全为1map[i][col - 1] = 1;//最后一列全为1}map[3][1] = 1;map[3][2] = 1;T t = new T();t.findWay(map, 1, 1);//初始位置为1,1//遍历地图for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[i].length; j++) {System.out.print(map[i][j]);}System.out.println();}}
}class T{//int[][] map, 传入地图。数组是引用类型,所以形参影响实参//int i, int j, 传入当前位置//递归终点是 map[row - 2][col - 2]//0 未走的路,1 障碍,2 可走的路,3 死路别走//策略 上右下左public boolean findWay(int[][] map, int i, int j){int row = map.length;int col = map[0].length;if (map[row - 2][col - 2] == 2) {return true;}else{if (map[i][j] == 0) {map[i][j] = 2;if (findWay(map, i + 1, j)) {//下return true;}else if(findWay(map, i, j + 1)){//右return true;}else if(findWay(map, i - 1, j)){//上return true;}else if(findWay(map, i, j - 1)){//左return true;}else{//上下左右都没路走,认定为死路map[i][j] = 3;return false;}}else{//1,2,3 1和3不能走,2:不能走回头路return false;}}}
}

汉诺塔问题
public class HanioTower{public static void main(String[] args) {Tower tower = new Tower();char a = 'A';char b = 'B';char c = 'C';tower.Move(3, a, b, c);}
}class Tower{//将汉诺塔的三个移动地点设成a, b, c.这是位置!!//再复杂的汉诺塔也想成俩//一是只有一层,a -> c//二是有两层,先移第一层,a -> b。再移第二层, a -> c。最后将 b -> c.public void Move(int num, char a, char b, char c){if(num == 1){System.out.println(a + " -> " + c);}else if(num > 1){//视作两层看待Move(num - 1, a, c, b);//第一层, a -> bSystem.out.println(a + " -> " + c);//第二层, a -> cMove(num - 1, b, a, c);//b -> c}}
A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C

八皇后问题

8 * 8 的国际象棋上,摆放8个皇后,使其不能相互攻击。即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少中摆法。

JAVA基础-U7 面向对象编程(基础部分)-递归相关推荐

  1. JAVA基础-U7 面向对象编程(基础部分)-作用域

    作用域 在java编程中,主要的变量就是属性(成员变量)和局部变量. 全局变量:也就是属性,作用域为整个类体.可以不赋值直接使用,因为有默认值. 局部变量:一般指的是在成员方法中定义的变量(除了属性之 ...

  2. JAVA基础-U7 面向对象编程(基础部分)-构造器

    构造方法/构造器 基本语法 构造方法又叫构造器(constructor),是类的一种特殊方法,它的主要作用是对新对象的初始化 [修饰符] 方法(形参列表){方法体; } 构造器的修饰符可以默认,也可以 ...

  3. JAVA基础-U7 面向对象编程(基础部分)-可变参数

    可变参数 基本概念 java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法 本质上是将其当成数组对待 基本语法 访问修饰符 返回类型 方法名(数据类型... 形参名){} 快速入门 ...

  4. JAVA基础-U7 面向对象编程(基础部分)-成员方法

    成员方法 快速入门 添加speak成员方法,输出"我是一个好人" 添加cal01成员方法,可以计算从1+-+1000的结果 添加cal02成员方法,该方法可以接受一个数n,计算从1 ...

  5. JAVA基础-U7 面向对象编程(基础部分)-类与对象

    类与对象(OOP) 快速入门 类是抽象的,概念的,代表一类事物.即它是数据类型 对象是具体的,实际的,代表一个具体事物.即它是实例 类是对象的模版,对象是类的一个个体,对应一个实例 养猫问题: 张老太 ...

  6. JAVA基础-U7 面向对象编程(基础部分)-方法重载

    方法重载(Overload) 基本介绍 java中允许同一个类中,多个同名方法的存在,但要求形参列表不一致 eg. System.out.println(); //out是PrintStream类型 ...

  7. [Java入门笔记] 面向对象编程基础(二):方法详解

    2019独角兽企业重金招聘Python工程师标准>>> 什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能 ...

  8. Java基础-初识面向对象编程(Object-Oriented-Programming)

    Java基础-初识面向对象编程(Object-Oriented-Programming) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Java是一门面向对象的程序设计语言.那么什 ...

  9. Java面向对象编程(基础部分)

    面向对象编程(基础部分) 类与对象 01: public class ObjectWorkDemo {public static void main(String[] args){Cat cat1 = ...

最新文章

  1. JUC 常用 4 大并发工具类
  2. C语言学习笔记(一)_hello world
  3. Pet Shop4解密配置文件
  4. opencv 星空_opencv各种小例子
  5. 登录验证---过滤器(Fileter)
  6. Identity Service - 解析微软微服务架构eShopOnContainers(二)
  7. [react-router] React-Router 4的switch有什么用?
  8. 关于Apache Tomcat解决localhost was unable to start within 45 seconds
  9. 使用php创建一个注册表单,如何实现一个简单的注册表单
  10. linux黑板模式,敲黑板!怎样使用 Linux stat 命令创建灵活文件列表?
  11. Spring Cloud云架构-Restful 基础架构
  12. 在3dmax中打开文件时,显示路径无效,如何处理?
  13. 网络层———IPv4(1)
  14. Windows Server 2008 R2 搭建网站详细教程
  15. 1.EKL在项目中担当的位置
  16. 第三十五天:XSS跨站反射存储DOM盲打劫持
  17. 学计算机要数学和英语怎么说,高中数学和英语有点恼火。但本人大学想学计算机,就是不知道英语和数学与计算机专业有什么必要联络吗?...
  18. 神奇的口袋 C++ 三种方法(枚举,递归,动态规划)
  19. Java中有指针么?
  20. 电磁场常见名词整理(不断更新中)

热门文章

  1. Nginx 调整文件上传大小
  2. 向量相减,作图进行证明
  3. codeforces F. Kate and imperfection
  4. Redundancy
  5. 在JFrame里画sin函数的图像
  6. HA Of Rancher
  7. 1067 例题5-7 求圆周率pi的近似值
  8. ac 无线二维码认证服务器,无线V7 AC配合Cisco ISE认证服务器实现portal认证配置
  9. 10分钟快速搭建自己的服务器
  10. python-字符串详细卷(懒虫期末总结)