码迷,mamicode.com
首页 > 其他好文 > 详细

递归原来可以so easy

时间:2018-10-09 16:14:46      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:出错   产生   数学   代码   程序   blog   故事   传递   编程模型   

引子

从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是......

这个例子,如果用java程序来演示,会是这个样子:

public class Hello {
    public static void main(String[] args) {
        sayStory();       
    }

    static void sayStory(){
        System.out.println("从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是");
        sayStory();
    }   
}

程序运行结果:

技术分享图片

故事在一直讲下去。

看一下java代码中,在方法sayStory()中又调用了sayStory()。

递归概述

什么是递归

  递归,英文为Recursion, 在计算机科学中,递归指得是在函数的定义中使用函数自身。
递归,包含了两个意思:递 和 归。递是只传递下去,归是指归来,也就是说,递归有去也有回。
那么,上面的讲故事的程序,算递归程序吗?
在方法sayStory()中又调用了sayStory(),符合递归的一个条件,即传递,但是,这个程序,没有归来,所以,程序会一直运行下去,直到资源耗尽,程序出错:

技术分享图片

因此,这不是个完整的递归程序。
递归要素
首先,递归必须要申明一个函数,且在函数中调用自身。
另外,递归要有明确的终止条件,递归就是有去有回,必然有一个明确的重点,到达这个终点后,就不再往下递,而是开始往回归来。

递归的内涵

? 递归的核心思想,就是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况,这也正是递归的定义所在。
考虑一下,递归的数学模型,很像数学归纳法。数学归纳法适用于将解决的原问题转化为解决它的子问题,而它的子问题又变成子问题的子问题。归纳法解决数学问题一般分为下面3个步骤:
1:步进表达式:问题演算成子问题的表达式
2:结束条件:什么时候可以不再使用步进表达式
3:求解表达式:在结束条件下能够直接计算返回值的表达式

比如,斐波那契数列,使用数学归纳法,3个步骤为:
1: 推导出计算表达式: F(n)=F(n-1)+F(n-2) (n≥3)
2:结束条件:n=1,n=2时
3:求解表达式: F(1)=F(2)=1

递归的编程模型

   明确了递归的数学模型后,我们就要看,如果通过编程来实现递归。一般的,有两种编程模型:

模型一: 先处理问题,然后再往下传递
递归函数(大规模){
if (end_condition){ // 递归终止条件
end;
}else{
solve; // 处理问题
递归函数(小规模); // 分解问题规模,传递下去
}
}

模型二: 在归来的过程中处理问题
递归函数(大规模){

    if (end_condition){      // 递归终止条件
        end; 
}else{ 
    递归函数(小规模);  //分解问题规模,传递下去
        solve;            // 归来,处理问题
    }
}

下面,演示一下,使用递归的编程模型,解决斐波那契数列问题。
首先,需要什么一个函数,问题规模为n,问题的结果为一个整数。
则函数可以声明为:int fib(int n)
然后,确定终止条件: n=1,n=2时
3:求解表达式:
F(n)=F(n-1)+F(n-2) (n≥3)
F(1)=1,F(2)=1

则代码如下:

技术分享图片

案例演示

阶乘

阶乘n!的数学定义: n!=1234…..(n-1)n,并规定 1!=1。
因此,2!=21=2(1!),3!=3(21)=3(2!),
4!=4
(321)=4(3!)
5!=5
(4321)=54!
根据规律,可以推断出: n!=n*(n-1)!,这就是阶乘的递归公式。
并且可以明确递归的终止条件n=1,终止时的值为1。

下面,想一下,如何用java程序来实现呢?
递归函数原型,可以什么为:int factorial(int n);
则函数的递归调用表达式为: factorial(n)=n* factorial(n-1)

具体代码如下:

public class Hello {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入n:");
        int n = sc.nextInt();
        int f = factorial(n);
        System.out.println("结果是:" + f);
    }

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

更多案例,请看下一章节。


源码、更多资深讲师相关课程资料、学习笔记请入群后向管理员免费获取,更有专业知识答疑解惑。入群即送价值499元在线课程一份。

QQ群号:560819979

敲门砖(验证信息):高山流水

递归原来可以so easy

标签:出错   产生   数学   代码   程序   blog   故事   传递   编程模型   

原文地址:http://blog.51cto.com/13477015/2296330

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!