趣学算法C系列半小时弄懂递归

开一个新系列,记录自己再次重新开始学C++的一些心得。

引子:什么是函数?

在基于C++程序求解问题的过程中,程序员经常会把一些常用的公式或者规律编写成函数(英文是function),这些具有一定功能的函数们,都放在函数库中供下次实现相关的功能时随意选用。

比如,我们都知道,1,,...,n这n个连续自然数和的计算公式是:

[(首项+末项)*(项数)]/

即:

S(n)=1++3+...+n=(1+n)n/

当你需要计算

1++3+...+10=?

那么你只需要在S(n)中令n=10即可。

因此,在C++中可以写出如下的函数:

#includeiostream#includecstdiousingnamespacestd;longleijia(longn){if(n==1){return1;}else{returnn+leijia(n-1);}}intmain(){intm;cinm;coutleijia(m)endl;return0;}

然后用它来计算任意n个连续自然数的和。是不是很方便?!

你可以对比一下直接计算的C++程序:

#includeiostreamusingnamespacestd;intmain(){inti,n,sum=0;cout"Howmanynumbers?";cinn;for(i=1;i=n;i++){sum+=i;}cout"Sum="sum;return8;}

再看看正整数的阶乘(n!)的计算:

#includeiostream#includecstdiousingnamespacestd;longlongjc(longlongn){if(n==1){return1;}else{returnn*jc(n-1);}}intmain(){intm;cinm;coutjc(m)endl;return0;}

由此可见,如果程序员能高效地利用函数这个工具,是可以大大减少重复编写代码的工作量的。

开胃菜:什么是函数递归?

有时,一件事可能是一个流程的重复进行,这事可能需要用到函数的递归(英文是Recursion)的思想。

比如:小时候玩过的汉诺塔(英文是TowerofHanoi)小游戏!

如上图:

有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状、叠放n个不同大小的圆盘,要把所有盘子一个一个移动到柱子C上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方。

问:至少需要多少次移动才能实现这一目标?

思考过程:

容易想象:在满足规则的前提下,如果完成把最大一个圆盘上的那n-1个圆盘从A柱挪到C柱共需要移动次数为H(n-1)。

那么,要把全部n个圆盘挪到C柱,只需要先把n-1个圆盘放到B柱上;然后,把最大的一块从A放在C上;再把B上的所有盘子移动到C上(本质上,这就是重复把最大一个圆盘上的那n-1个圆盘从A柱挪到C柱的操作)。

由此,你会发现:

H(1)=1

H(n)=H(n-1)(第一阶段)+1(第二阶段)+H(n-1)(第三阶段)

即:

H(n)=*H(n-1)+1(n1)

用递归思想写出来的程序是:

#includeiostream#includecstdiousingnamespacestd;longhnt(longn){if(n==1){return1;}else{return*hnt(n-1)+1;}}intmain(){intm;cinm;couthnt(m)endl;return0;}

题外话:

根据H(n)=^n-1(n0)能不能求出它的具体表达式呢?

当然可以!

等你读了中学,有了一定的数学基础,你很快就能得到H(n)的一般式:

H(n)=^n-1(n0)

带入n值,你就知道挪汉诺塔大致需要多少次了!

但爸爸说,这是个差分方程,直到中学才会学,它也容易求解,目前我们小学生可能暂时不需要知道怎么求解,:)

那,我们就暂时不需要管它了!

正餐来了:递归函数编写策略

再看几个经典的递归问题吧!

斐波那契数列的第n项=?

先介绍一下这个有趣的数列:

斐波那契数列(Fibonaccisequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(LeonardoFibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。

它指的是这样一个数列:

1、1、、3、5、8、13、1、34、……

在数学上,斐波那契数列以如下被以递推的方法定义:

F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-)(n≥,n∈N*)

在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。

更详细的介绍可参见:


转载请注明:http://www.aierlanlan.com/rzgz/34.html