递归说白了就是程序调用自身。
与递推思想相比,递归就是递推的反向过程。
递归的分析思路可以总结为4步:
1、寻找递推关系
2、寻找临界条件
3、总结递归表达式
4、改写成递归函数
举个最简单的栗子:
求整数1到100的和。
分析:
1、关系:
很明显,第n项是前1个数字加1,f(n)=f(n-1)+1、前n项和sum(n)=sum(n-1)+n;
2、临界:
很明显,当n等于1时,sum值为1;
3、表达式:
s
u
m
(
n
)
=
{
1
,
n
=
1
s
u
m
(
n
−
1
)
+
n
,
n
>
1
sum(n)= \left \{\begin{array}{cc} 1, & n=1\\ sum(n-1)+n, & n>1 \end{array}\right.
sum(n)={1,sum(n−1)+n,n=1n>1
4、函数:
// 求第n项
function fn(n){
if(n==1) return 1;
return fn(n-1)+1;
}
// 求前n项和
function sum(n){
if(n==1) return 1;
return sum(n-1)+n;
// return sum(n-1)+fn(n);// 也可以调用fn()
}
sum(100);
完事!
是不是很简单!
再举个栗子:
求一个数的阶乘。
分析:
1、关系:
很明显,n就是前1项的阶乘*n,f(n)=f(n-1)*n;
2、临界:
很明显,当n等于1时,sum值为1;
3、表达式:
f
n
(
n
)
=
{
1
,
n
=
1
f
n
(
n
−
1
)
∗
n
,
n
>
1
fn(n)= \left \{\begin{array}{cc} 1, & n=1\\ fn(n-1)*n, & n>1 \end{array}\right.
fn(n)={1,fn(n−1)∗n,n=1n>1
4、函数:
var num=prompt("请输入一个数,以计算其阶乘")
console.log(fn(num));
function fn(n){
// 第一种写法 常规写法
if(n==1) return 1;
return fn(n-1)*n;
// 第二种写法
if(n==1){}
else{n*=fn(--n)}
return n;
// 第三种写法
if(n!=1){n*=fn(--n)}
return n;
}
是不是很简单!
接下来做个有难度的经典题:
求斐波那契数列的第n项及前n项和。
首先斐波那契数列是1,1,2,3,5,8,13,21…
即第n项是前两项的和。
什么意思?f(n)=f(n-1)+f(n-2),就这么个关系。
那极限临界呢?
很明显,斐波那契数列前2项必须是1和1。
什么意思?f(1)=1;f(2)=1,就这么个意思。
那表达式就出来了:
f
n
(
n
)
=
{
1
,
n
<
=
2
f
n
(
n
−
1
)
∗
n
,
n
>
2
fn(n)= \left \{\begin{array}{cc} 1, & n<=2\\ fn(n-1)*n, & n>2 \end{array}\right.
fn(n)={1,fn(n−1)∗n,n<=2n>2
那前n项和呢?
和第一个栗子求和一样的啊,调用fn()就行了。
s
u
m
(
n
)
=
{
1
,
n
=
1
s
u
m
(
n
−
1
)
+
f
(
n
)
,
n
>
1
sum(n)= \left \{\begin{array}{cc} 1, & n=1\\ sum(n-1)+f(n), & n>1 \end{array}\right.
sum(n)={1,sum(n−1)+f(n),n=1n>1
接下来改写成函数代码:
// 计算第n个数
function fn(n){
if(n==1||n==2) return 1;
//if(n<=2) return 1; // 也可以写成这样
//if(n<=1) return n; // 还可以写成这样
return fn(n-1)+fn(n-2);
}
// 计算前n项的和
function sum(n){
if(n==1) return n;
return sum(n-1)+fn(n);
}
console.log(fn(2),sum(7)); // 1, 33
在下面这篇博客里,
https://blog.csdn.net/PrisonersDilemma/article/details/89454382
我列出几个经典题目,可以自己分析分析。
关系→临界→表达式→函数