| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1319 人关注过本帖
标题:汉诺塔 理解不了怎办???
只看楼主 加入收藏
helloUJS
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:168
专家分:731
注 册:2013-3-27
收藏
得分:0 
回复 10楼 々NARUTO
我个人觉得你对递归的理解有些偏差,如果要设计一个递归函数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);
      }
}

[ 本帖最后由 helloUJS 于 2013-5-4 13:48 编辑 ]
2013-05-04 13:46
々NARUTO
Rank: 2
等 级:论坛游民
帖 子:80
专家分:85
注 册:2011-6-19
收藏
得分:0 
以下是引用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
--------------------------------------------------------------------------------------------------------------------------------
2013-05-04 19:03
快速回复:汉诺塔 理解不了怎办???
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.032434 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved