递归是程序设计中常用到的一种简单易懂的方法,在很多场合下,利用递归可以大量减少代码量。

递归往往能体现设计者头脑的聪慧,简单的递归函数省去了大段大段的代码,让人叹服不已。那么,递归的设计又有怎样的固定思路呢?本文将介绍递归与数学归纳法之间的联系,希望给读者一些启迪。

数学归纳法是数学中重要的一种证明方法。当证明一个数学定理时,采用数学归纳法的思路是,先证明对于简单的可以代入的数,定理成立;再在假设定理对某一数N成立的前提下,证明N+1也是定理成立。其实,数学归纳法利用的是递推的原理,形象地可以叫做多米诺原理。因为N+1的成立就可以向前向后递推所有数都成立。

而递归利用的也是递推的原理,在整个程序中,反复实现的将是同一个原理。在这一点上,递归与数学归纳法本质是相同的。所以往往可以利用数学归纳法来设计递归的实现。计算机是数学应用的一个分支在这里体现的淋漓尽致。

这里我们先来看一个例子,非常简单,设计一程序,求自然数N的阶乘N!:

现在已知N!=N*(N-1)*(N-2)*(N-3)*…*2*1

首先可知当N=1时 N!=1

第二步可设当R(N)=N!,R(N+1)=(N+1)!

第三步,求R(N+1)与R(N)之间的关系。R(N)=N!,

而R(N+1)=(N+1)!=(N+1)*(N)*(N-1)*…*2*1=(N+1)*N!=(N+1)*R(N)

即:R(N+1)=(N+1)*R(N)=〉R(N)=N*R(N-1)

现在根据这个公式草略地构造一个函数:

factorial (int N)

{

return N *factorial (N - 1)   /*    递归部分    */

}接下来补充截止部分,这一部分在整个过程中只使用一次,没有它,程序就将无限递归下去。可以说它是程序运行栈的栈顶,到了它,就开始一步步退栈了。

函数改为:    factorial (int N)

{

if (N == 1)   return 1;

return N *factorial (N - 1)   /*    递归部分    */

}

上面的步骤是可以颠倒的,而且首先设计截至部分还要好一些。

现在来总结设计递归程序的步骤:

一、用数学归纳法分析问题,根据数学归纳法的第一步得出截至部分。二、根据数学归纳法的第三步来构造函数的递归部分。其实这个求解过程就是找出R(N)与R(N-1)的关系式。    现在利用总结出的方法做一个练习,比较经典的汉诺塔。

汉诺塔想必大家都知道:三个立柱(命名为from、temp、to,from为圆盘初始所在立柱、to是目标立柱),N个直径不相等的圆盘,将圆盘从from上一个一个移动在to上,要求,每次只能移动一个圆盘,而且只能在三个立柱之间移动。不能出现大盘压小盘的情况。

首先用数学归纳法分析:

当只有一个圆盘的时候,我们可以确定唯一动作:直接将圆盘从from移动到to上。

现在假设有N个圆盘在from上,而我们可以将这些圆盘最终按要求移动到to上(当然也可以移动到temp上)。

那么我们可以证明如果有N+1个时候,我们也可以将圆盘全部按要求移动到to上:因为我们可以先将上面的N个移动到temp上(第二步已假设),再把剩下的最后一个移动到to上,再把temp上的移动到to上。按照我们总结过的递归函数设计步骤来设计程序:

首先,确定截至部分:当只有一个圆盘移动的时候,直接将它移动到to上。即:if (n == 1) move (n,  from, to);

(这里的move函数意义是将n号圆盘,或者说初始状态下从上面数第n个圆盘,从from移动到to)

第二步确定递归部分,其实就是N+1与N的关系部分,就是红色字体部分。现在开始把文字转化为程序:

设Hanoi (int n, int from, int temp, int to)函数就是我们要求的汉诺塔实现函数,意义是将按直径递增摞在一起的n个圆盘从from按要求移动到to上,temp为辅助圆盘。可写出代码:

Hanoi (n-1, from, temp);   /*先将上面的N个移动到temp上*/

move (n, from, to);   /*剩下的最后一个移动到to上*/

Hanoi (n-1, temp, to);   /*再把temp上的移动到to上*/

第二步完成,最后合成函数:

void

Hanoi (int n, int from, int temp, int to)

{

if (n == 1)

move (n, from, to);

else

{Hanoi (n-1, from, temp);move (n, from, to);Hanoi (n-1, temp, to);

}

}

使用数学归纳法设计递归程序最大的好处就是可以使设计者摆脱对递推的顾虑。因为你设计的代码必定隐含着递推的步骤。直接根据你的分析文字转化为代码即可。

public void moveit(int n, ref Stack src, ref Stack des)

{

if ( src.Count!=0)

{

int varTemp;

varTemp = (int)src.Pop();

if(des.Count!=0)

{

if (varTemp < (int)des.Peek())

{

des.Push(varTemp);

}

else

src.Push(varTemp);

}

else

des.Push(varTemp);

}

}

public void hanoi(int n,ref Stack from, ref Stack tmp, ref Stack to)

{

if (n==1)

moveit(n,ref from, ref to);

else

{

hanoi(n-1, ref from, ref to, ref tmp);

moveit(n, ref from,ref to);

hanoi(n-1, ref tmp, ref from, ref to);

}

}

java中数学归纳法_递归设计与数学归纳法相关推荐

  1. java中的方法递归

    JAVA中的方法递归 递归的思路 代码举例 一.递归的思路 一个方法在执行时,调用自身被称为"递归". 递归相当于数学归纳法,有一个起始条件,有一个递推公式. 递归可以分为:单路递 ...

  2. Java中函数及递归的使用(附思维导图)——java面试知识点

    引言 我相信能点到这里来的童鞋们对计算机编程中的函数肯定已经有或多或少的认知,首先我们需要知道的是:计算机编程语言中的"函数"和它隔壁领域--数学中的同名同姓的亲戚"函数 ...

  3. java中单根_通俗易懂的告诉你什么是java的单根继承结构

    花10分钟认真的看完一篇文章,或许会有意想不到的收获! 我们都知道java是单继承的,就是一个类只能extends一个父类.但是你知道吗,其实java中有一个类是所有类的父类,就是Object类,这是 ...

  4. 利用java中for循环,递归解决机选双色球问题

    利用java中简单的for循环,if判断和递归思想,解决机选双色球的问题 public static void main(String[] args) { /** * 双色球的选取共有两部分,红球和蓝 ...

  5. java bundle管理_架构设计——OSGI规范

    架构设计--OSGI简介 一.OSGI简介 1.OSGI简介 OSGI(Open Service Gateway Initiative),即开放服务网关协议,是面向Java的动态模型系统. OSGI是 ...

  6. java中引用类型_您真的了解Java中的4种引用类型吗?

    Java中提供了四个级别的引用:SoftReference,FinalReference,WeakReference和PhantomReference.在四种引用类型中,只有FinalReferenc ...

  7. java中同步_在Java中的方法同步和语句同步(块同步) - Break易站

    Java 多线程 线程主要通过共享对字段的访问和参考字段引用的对象进行通信.这种通信形式非常有效,但可能出现两种错误:线程干扰和内存一致性错误.需要一些同步构造来防止这些错误.以下示例显示了我们需要同 ...

  8. 如何设计java线程安全类_如何设计线程安全的Java程序

    什么是线程安全的(thread-safe)? 在java中,线程安全的指的是代码可以在并发的或者多线程的环境下安全的使用或者共享,并且它们都将按照期望的方式运行.任何代码,类或者对象,如果它们在并发的 ...

  9. 在java中为什么_属性绑定到类型_方法绑定到对象_13. Java基础之类型信息(RTTI和反射)...

    一. Java反射机制介绍 Java 反射机制.通俗来讲呢,就是在运行状态中,我们可以根据"类的部分已经的信息"来还原"类的全部的信息".这里"类的部 ...

最新文章

  1. 任意给4条边求形成四边形面积最大值
  2. 针对C++和Delphi的LiveBindings一瞥
  3. 同样版本的jstl,都是jstl1.2版本,有个有问题,另一个没有问题
  4. exports,和module.exports 的区别
  5. Oracle全文索引之一 原理
  6. 数据库增加列或删除列操作
  7. 【报告分享】中金103页区块链行业报告:区块链与数字货币,科技如何重塑金融基础设施.pdf(附下载链接)
  8. CentOS系统时间与网络同步
  9. 生于资本,死于泡沫,review ofo衰亡
  10. RTI_DDS自定义插件开发 5 专属区域(_xxEA)
  11. python 绘图及可视化
  12. [随笔]_ELVE_git命令复习
  13. ChatGPT飙升苹果商店榜首,每周订阅需7.99美元,结果是个假的???
  14. C++程序设计课程设计报告——自助点餐系统
  15. 银河麒麟用QIFW制作安装包
  16. CRUD是什么意思?
  17. APUE读书笔记-第十一章-线程
  18. Console线连接交换机路由器等设备
  19. 基于Halcon学习的二维码识别【一】micro_qr_simple.hdev
  20. 《哈利波特》电影全集+有声书免费领取!带你重返儿时魔法世界……

热门文章

  1. CentOS 8 结束生命周期,我们怎么办
  2. U盘的工作原理(读取和存储数据)
  3. 为什么变频空调省电的原理和分析
  4. 一款生成gif图片的工具
  5. sqlmaphttrack
  6. 【数据分析】零售商品案例——存货分析
  7. python QQ群发剪贴板消息
  8. 惠普德国裁员1400人 大部分将来自EDS
  9. 微信小程序url:XXX不在以下request合法域名列表中怎么解决?
  10. 获取节点的所有属性 neo4j