以下是引用helloUJS在2013-5-4 13:46:25的发言:
我个人觉得你对递归的理解有些偏差,如果要设计一个递归函数fun(n),只要能把fun(n)转换成fun(n-1)的问题,并且当n为特定值时(比如n=1)问题的答案是已知的,就可以了,而不必关心fun(n-1)是如何计算出来的,这正是递归的优势,因为如果搞清楚fun(n-1)的情况,那就直接用循环就可以了,因为递归需要更多的资源,速度也没有循环快,实际上一个问题只要能转换成一个分段函数的形式,使用递归实现是非常方便的。如下几个例子不知是否有助于理解递归:
1. s(n)=1+2+3+.....+n
1 当n=1时
s(n)=
s(n-1)+n 当n>1时 不必关心s(n-1)如何计算出
对应的递归函数:
int S(int n)
{
int sum;
if(n==1)
sum=1;
else
sum=S(n-1)+n; /*不必关心如何计算出S(n-1)*/
return sum;
}
2. S(a,b)=f(x)在[a,b]上的定积分
假设运用矩形法计算,S(a,b)可以转换成如下分段函数:
f(a)*(b-a) 当|a-b|足够小(比如小于1e-6)
S(a,b)=
S(a,(a+b)/2)+S((a+b)/2,b) 当|a-b|>1e-6时 不必关心S(a,(a+b)/2)和S((a+b)/2,b)如何计算出来
对应的递归函数是:
float S(float a,float b)
{
float sum;
if(fabs(a-b)<=1e-6)
sum=f(a)*(b-a); /*假设f(x)已经定义*/
else
sum=S(a,(a+b)/2)+S((a+b)/2,b); /*不必知道S(a,(a+b)/2)如何计算出来*/
return sum;
}
3. bprint(n)=打印出十进制数n对应的二进制
打印n 当n<2时
bprint(n)=
bprint(n/2) 当n>2时,先打印n/2对应的二进制,然后再打印n对应的二进制的最后1位(n%2)
打印 n%2
对应的递归函数:
void bprint(int n)
{
if(n<2)
printf("%d",n);
else
{
bprint(n/2); /*不必关心如何打印出n/2对应的二进制*/
printf("%d",n%2);
}
}
非常感谢你整理的那些资料
------------------------------------------------------------------------------------------------------------------------------
其实 我的话 主要是被 伪代码 给糊涂了
我记得伪代码 当初 有句是这样写的
将f1借助f3移到f2
这样的话 搞得我当初 总是有一种
直线的思维 就是
f1是第一根柱子 f3是第三根柱子 f2是第二根柱子
这样理解的话 就是
所有的n-1,n-2,n-3...的盘子都从第一根借助第三根移到第二根
搞得我对从程序源码的实现这些 都糊涂了好多 那程序思想明明和代码不符.
所以刚开始 我说了这些话
// 调用此函数说是为了借助f3从f1移到f2
//可是这调用的实参和形参都是颠倒的,也就是说第一次调用是移到了f2但是,第二次由于形参和
//实参的颠倒 ,表面上看去是已到了f2实际上是移到了f3.
还说了 什么程序如何 遵循那个思想的...............
还是到后面 才
怀疑起来 那样的话可以直接写个
hanuota('a','c','b')而无需hannuota(f1,f3,f2),f3真的只代表的是第三根柱子吗?
主要就是在这里一点 才豁然开朗.
--------------------------------------------------------------------------------------------------------------------------------
The End,Thank U Very Much... 2013.5.4
--------------------------------------------------------------------------------------------------------------------------------