关于java中的递归

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于java中的递归相关的知识,希望对你有一定的参考价值。

参考技术A hi(n
+
1);
System.out.println("你好"
+
n);
这两句调换一下,就不会反了。
因为最后一个递归调用最先返回,而第一次打印就是在这个返回之后调用的。
执行过程:
main->hi(1)->hi(2)->hi(3)...hi(20)。
hi(19):
hi(20)返回,
print(19).
返回
hi(18):
hi(19)返回,
print(18).
返回
...
hi(1):hi(2)返回,print(1).返回
main:
下一句,退出.
递归只重复函数的内容。
如果是非引用型参数,其值在递归返回后不会受影响。这个跟普通的函数调用没有区别。
但是,递归需要注意两个基本问题:
1)
必须要有终止条件。
2)
递归层次不能太深,否则可能引起调用栈溢出,导致程序崩溃。

初次接触java中的递归算法

一道关于兔子繁衍的编程题:

有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

自己考虑了挺久,思路出现了问题,甚至连其中的规律都没有搞清楚.查看网上的一些算法之后,发现一个之前没有使用的思想:递归.目前对于递归的理解仅限于初级中的初级.

关于这道编程题,应该以这样的思路来进行考虑:

每个月的兔子的来源是哪些?答:上个月的兔子的个数(不管是否具备繁殖能力) + 2个月前的兔子的个数  在第1和2个月的时候,只有最开始的一对兔子.

这样想一想的话,就是用上个月的兔子个数 + 上上个月的兔子个数 ,就可以得到本月的兔子的个数.结果恰好是很著名的斐波那契数列.

 

1     public static int method(int month){
2         if(month == 1 || month == 2){
3             return 1;
4         }else{
5             int num =  method(month -1) + method(month -2);
6             return num;
7         }
8     }

 

 

 

思想就是结果= 上次程序的结果 + 上上次的程序的结果

后在网上查看有关递归的资料,看到另外两个用递归思想解决的问题:爬楼梯问题和汉诺塔问题

 

爬楼梯问题

假设一个楼梯有 N 阶台阶,人每次最多可以跨 M 阶,求总共的爬楼梯方案数。

分析:

台阶数(走法) 方法数
1 1 1
2 11 2 2
3 111 12 21 3
4 1111 112 121 211 225

因此可知,这个问题和之前的兔子繁衍问题是一个道理.

 1 public static int f(int n) {
 2         if (n == 0) {
 3             return 0;
 4         } else if (n == 1) {
 5             return 1;
 6         } else if (n == 2) {
 7             return 2;
 8         } else {
 9 
10             return f(n - 1) + f(n - 2);
11         }
12     }

 

 

汉诺塔问题:

从左到右 A B C 柱 大盘子在下, 小盘子在上, 借助B柱将所有盘子从A柱移动到C柱,大盘子只能在小盘子下面.

这些问题我想起来比较吃力,但网上解析很多,几乎涵盖了我的所有的考虑了,因此,我在这里只说以下较为简单快捷的一种理解方式.

 

A,B,C三个针,假设有n个盘子,只需要分成三步,①将(n-1)个盘子从A移动到B,②将最大的盘子从A放到C,③将(n-1)个盘子从B移动到C

f(n) = (f(n-1)*2) + 1;

public static int method(int n){
        if(n == 1){
            return 0;
        }else if(n == 2){
            return 1;
        }else{
            return method(n-1)*2 + 1;
        }
    }

 

再举个例子,使用递归的思想来打印9*9乘法表

正常若不使用迭代的话,可以这样来实现代码,使用两层嵌套的for循环

1 public static void method_1(){
2         for(int i = 1;i <= 9;i++){
3             for(int j = 1;j <= i;j++){
4                 System.out.print(i + "*" + j + "=" + i*j + " ");
5             }
6             System.out.println();
7         }
8     }

若使用递归的话,问题就变成了:打印上一次的结果并打印新的一行

 1 public static void method_2(int i){
 2          if (i == 1) { 
 3              System.out.println("1*1=1 "); 
 4          } else { 
 5              method_2(i - 1); 
 6              for (int j = 1; j <= i; j++) { 
 7                  System.out.print(j + "*" + i + "=" + j * i + " "); 
 8              } 
 9              System.out.println(); 
10          } 
11     }  

 

关于递归的应用,大体上来说,就是需要发现并找到程序中的递归的情况,将问题简化.

 







以上是关于关于java中的递归的主要内容,如果未能解决你的问题,请参考以下文章

Java实验--关于简单字符串回文的递归判断实验

关于 Java 新手的递归

初次接触java中的递归算法

递归 - 与数组结合,Java 中不重复

关于JavaScript对象深度克隆

java中方法的递归调用