引子
从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是......
这个例子,如果用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);
}
}
更多案例,请看下一章节。