1 什么是递归调用

1.1 概念

  递归调用是一种特殊的嵌套调用,是某个函数调用自己或者是调用其他函数后再次调用自己的,只要函数之间互相调用能产生循环的则一定是递归调用,递归调用一种解决方案,一种是逻辑思想,将一个大工作分为逐渐减小的小工作,比如说一个和尚要搬50块石头,他想,只要先搬走49块,那剩下的一块就能搬完了,然后考虑那49块,只要先搬走48块,那剩下的一块就能搬完了,递归是一种思想,只不过在程序中,就是依靠函数嵌套这个特性来实现了。

1.2 定义

  递归调用就是在当前的函数中调用当前的函数并传给相应的参数,这是一个动作,这一动作是层层进行的,直到满足一般情况的的时候,才停止递归调用,开始从最后一个递归调用返回。

2、递归详情

调用前

  • 一个函数的运行期间调用另一个函数,在运行被调用函数之前,系统需要完成3件事
  1. 将所有的实参、返回地址等信息传递给被调用函数保存;
  2. 为被调用函数的成员变量分配存储区;
  3. 将控制转移到被调用的函数入口

调用中

  • 而从被调用函数返回调用函数之前,系统也应该完成3件工
  1. 保存被调函数的计算结果
  2. 释放被调函数的数据区
  3. 依照被掉函数保存的返回地址将控制转移到调用函数。当有多个函数构成嵌套调用时,按照后调用先返回的原则

递归函数特点

  • 所有递归函数的结构都是类似的。
  1. 函数要直接或间接调用自身。
  2. 要有递归终止条件检查,即递归终止条件满足后则不会再调用自身函数,一定要避免造成死循环
  3. 如果不满足递归终止的条件,则调用涉及递归调用的表达式。在调用函数自身时,有关终止条件的参数要发生变化,而却需要向递归中的方法变化

总结:

  • 函数的调用原则和数据结构栈的实现式一致的。也说明函数调用时通过栈实现的。

3、递归的简单示例

  • 案例一 :用递归方式实现99乘法表
public class test1112 {
    @Test
    public void test1() throws IOException {
        cont(9);
    }
    public void cont(int num){
        if (num==1){
            System.out.println("1x1=1");
        }else {
            cont(num-1);
            for (int i=1;i<=num;i++){
                System.out.print(num+"x"+i+"="+i*num+"  ");
            }
            System.out.println("");
        }

    }
}

	//输出结果
	1x1=1
	2x1=2  2x2=4  
	3x1=3  3x2=6  3x3=9  
	4x1=4  4x2=8  4x3=12  4x4=16  
	5x1=5  5x2=10  5x3=15  5x4=20  5x5=25  
	6x1=6  6x2=12  6x3=18  6x4=24  6x5=30  6x6=36  
	7x1=7  7x2=14  7x3=21  7x4=28  7x5=35  7x6=42  7x7=49  
	8x1=8  8x2=16  8x3=24  8x4=32  8x5=40  8x6=48  8x7=56  8x8=64  
	9x1=9  9x2=18  9x3=27  9x4=36  9x5=45  9x6=54  9x7=63  9x8=72  9x9=81

思考: 为什么输出结果时,算式的结构顺序是这样的

  • 这是因为函数的实现是通过栈实现的,符合栈顺序,虽未的栈顺序就像枪的弹夹一样
  • 也可以参考这个图

JAVA递归调用的优缺点 java函数递归调用_JAVA递归调用的优缺点

  • 案例二 :使用Java代码求5的阶乘
public class test1112 {
    @Test
    public void test1() throws IOException {
        System.out.println(fn(5));
    }
    public long fn(int num){
        if (num==1){
            return 1;//设置了临界条件,当num-1=1的时候就结束递归
        }else {
           return  num*fn(num-1);
        }

    }
}
  • 案例三:使用Java代码求数列1,1,2,3,5,8…的第40位数
public class test1112 {
    @Test
    public void test1() throws IOException {
        System.out.println(fn(40));
    }
    public long fn(int num){
        if(1==num||2==num){
            return 1;
        }else {
            return fn(num-1)+fn(num-2);
        }
    }
}

JAVA递归调用的优缺点 java函数递归调用_JAVA递归调用的优缺点_02