递归的理解和例子
目录
1,递归的理解
递归的一个要素和两个条件
一个要素:想达到什么目的。这个是前提,知道想要的达到目标,就有方向了。
两个条件:
1,递归的结束条件:
结束条件就是什么时候停止递归。
2,递归的规律是什么?找到第n个数和第n-1之前数字的关联(自身调用)
规律嘛,用中学时代的数学题目就好理解了。
数学例子1:1到n累加
例子1:1累加到n的和
比如从1累加到n,规律是啥:
我们都知道 1+2+3+…(n-1)+n = n(n+1)/2;
第n个数,跟第n-1个数有什么关系呢?
更直观点用数字来说:
sum(1)+2 = 1 + 2
sum(2)+3 = 1+2+3
sum(3)+4 = 1+2+3+4
sum(4)+5 = 1+2+3+4+5
以此类推,可以归纳得到 第n个的值的和为:sum(n) = sum(n-1)+n, n≥1
同理:n阶乘的和: 1*2*3*…*(n-1)*n的递归为 multiply (n) = multiply(n-1)*n, n≥1
数学例子2:斐波那契数列
斐波那契数列: 1、1、2、3、5、8、13、21、34…n
这串数字的规律是什么?从第3个数字开始,每个数字等于前两个数字之和。归纳地推公式为:F(n)=F(n-1)+F(n-2),n≥3,F(1)=1,F(2)=1
数学例子3: 递增序列
数字序列1 : 2、3、5、9、17、… 、n
规律: 1+1,1+2,1+4,1+8,1+16:
归纳递推的规律是: 2(n-1)+1;
F(n)=F(n-1)*2-1,F(1)=2,n ≥2
复杂一点的数学序列2:
7、11、19、35、67、… 、n
规律:2 + 4 + 8 + 16 + 32
7、11、19、35、67
得到:
当前的数跟前一个数的关系:
11 = (7 -3 )*2 + 3;
19 = (11 -3 )*2 + 3;
35 = (19 -3 )*2 + 3;
归纳递归可以看出,第n个数,是第n-1个数减3,乘以2再+3;
F(n)= (F(n-1) -3 ) * 2 + 3; F(1)=7, n ≥2
对于有规律的数字,都可以用递归的方式去写,找到第n个数和第n-1之前数字的关联
递归算法的一般形式:
func( mode){
if(endCondition){ //递归出口,结束的条件
end;
}else{
func(mode_next) //调用本身,递归
}
}
递归的理解:用数学例子中的递增序列为讲;
代码:
/*目标: 计算第N个的数值
序列: 2、3、5、9、17、… 、n
递归: F(n)= (F(n-1) -3 ) * 2 + 3; F(1)=7, n ≥2
*/
public static int getIncres(int n) {
if (n >= 1){
if(n == 1){
System.out.println("压栈结束,开始出栈,回归的: "+7);
return 7;
}else{
System.out.println("压栈:递进的: "+ n);
int temp = (getIncres(n-1 )-3)*2+3;
System.out.println("出栈:回归的: "+ temp);
return temp;
}
}
return -1;
}
测试:
public static void main(String[] args) {
getIncres(5);
}
结果:
压栈:递进的: 5
压栈:递进的: 4
压栈:递进的: 3
压栈:递进的: 2
压栈结束,开始出栈,回归的: 7
出栈:回归的: 11
出栈:回归的: 19
出栈:回归的: 35
出栈:回归的: 67
先进行 getIncres(n-1 )方法的执行,知道n==1即递归结束,这过程中在入栈,然后回归,即出栈,具体执行 (getIncres(n-1 )-3)*2+3 得到具体的数值。
递归中的“递”就是入栈,递进;“归”就是出栈,回归。
2,数学例子java实现
1,数的累加
代码:
/*目标: 计算第N个的数值累加的和
序列: 1+2+3+…+(n-1)+n
递归: F(n) = F(n-1)+n, n≥1
*/
public static int getAggreAum(int n) {
if (n >= 1) {
if (n == 1) {
System.out.println("压栈结束,开始出栈,回归的:"+ n + "=1");
return 1;
} else {
System.out.println("压栈:递进的:"+ n);
int temp = n + getAggreAum(n - 1);
System.out.println("出栈:回归的:"+ n + "=" + temp);
return temp;
}
}
return -1;
}
测试:
public static void main(String[] args) {
getAggreAum(10);
}
结果:
压栈:递进的:10
压栈:递进的:9
压栈:递进的:8
压栈:递进的:7
压栈:递进的:6
压栈:递进的:5
压栈:递进的:4
压栈:递进的:3
压栈:递进的:2
压栈结束,开始出栈,回归的:1=1
出栈:回归的:2=3
出栈:回归的:3=6
出栈:回归的:4=10
出栈:回归的:5=15
出栈:回归的:6=21
出栈:回归的:7=28
出栈:回归的:8=36
出栈:回归的:9=45
出栈:回归的:10=55
2,数的阶乘
代码:
/*目标: 计算第N个的数值相乘的值
序列: 1*2*3*…*(n-1)*n
递归: F(n) = F(n-1)*n, n≥1
*/
public static int getFactorial(int n) {
if (n >= 1) {
if (n == 1) {
System.out.println("压栈结束,开始出栈,回归的:"+ n + "!=1");
return 1;
} else {
System.out.println("压栈:递进的:"+ n);
int temp = n * getFactorial(n - 1);
System.out.println("出栈:回归的:"+ n + "!=" + temp);
return temp;
}
}
return -1;
}
测试:
public static void main(String[] args) {
getFactorial(5);
}
结果:
压栈:递进的:5
压栈:递进的:4
压栈:递进的:3
压栈:递进的:2
压栈结束,开始出栈,回归的:1!=1
出栈:回归的:2!=2
出栈:回归的:3!=6
出栈:回归的:4!=24
出栈:回归的:5!=120
3,斐波那契数列
代码:
/*目标: 计算第N个的数值
序列: 1、1、2、3、5、8、13、21.....n
递归: F(n)=F(n-1)+F(n-2),n≥3,F(1)=1,F(2)=1
*/
public static int getFibo(int n){
if (n >= 0){
if (n == 0 || n == 1){
// System.out.println("压栈结束,开始出栈,回归的: "+n);
return n;
}
else{
// System.out.println("压栈:递进的: "+ n);
int fibo1 = getFibo(n - 1) ;
int fibo2 = getFibo(n - 2);
// System.out.println("出栈:回归的: "+ fibo1+ " 和 "+ fibo1);
return fibo1 + fibo2;
}
}
return -1;
}
测试:
public static void main(String[] args) {
System.out.println(getFibo(7));
}
结果: 13
总结:
递归主要是理解“递归中的“递”就是入栈,递进;“归”就是出栈,回归”这一个过程,执行的时候,先入栈,直到临界条件,然后进行出栈,执行具体的操作。
经典递归的例子: 二分法排序